From 1d8d23e9699546c069c417ea0cbdf39068f9d085 Mon Sep 17 00:00:00 2001 From: Perry Smit Date: Mon, 15 Jun 2020 08:43:00 +0200 Subject: [PATCH 001/202] Update 03_1_Verifying_Your_Bitcoin_Setup.md Change the line alias brstop="bitcoin-cli -regtest -stop" into alias brstop="bitcoin-cli -regtest stop" --- 03_1_Verifying_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_1_Verifying_Your_Bitcoin_Setup.md b/03_1_Verifying_Your_Bitcoin_Setup.md index 8332d16..4b84ee9 100644 --- a/03_1_Verifying_Your_Bitcoin_Setup.md +++ b/03_1_Verifying_Your_Bitcoin_Setup.md @@ -75,7 +75,7 @@ alias brstart="bitcoind -regtest -daemon" alias bcstop="bitcoin-cli stop" alias btstop="bitcoin-cli -testnet stop" -alias brstop="bitcoin-cli -regtest -stop" +alias brstop="bitcoin-cli -regtest stop" alias bcdir="cd ~/.bitcoin/" #linux default bitcoin path alias btdir="cd ~/.bitcoin/testnet" #linux default bitcoin testnet path From 4d7b7fe828c8d3b5663d0bde958afe44db2c71cb Mon Sep 17 00:00:00 2001 From: Perry Smit Date: Mon, 15 Jun 2020 14:29:01 +0200 Subject: [PATCH 002/202] Update 04_2__Interlude_Using_JQ.md signrawtransaction is deprecated, should be signrawtransactionwithwallet --- 04_2__Interlude_Using_JQ.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/04_2__Interlude_Using_JQ.md b/04_2__Interlude_Using_JQ.md index 71bfc78..ff6d3e3 100644 --- a/04_2__Interlude_Using_JQ.md +++ b/04_2__Interlude_Using_JQ.md @@ -21,7 +21,7 @@ _What is JQ?_ The repository explains it best, saying "jq is like sed for JSON d In the previous section, the use of `signrawtransaction` offered an example of not being able to easily capture data into variables due to the use of JSON output: ``` -$ bitcoin-cli signrawtransaction $rawtxhex +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex { "hex": "0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", "complete": true @@ -33,18 +33,18 @@ To use JQ, run `jq` at the backend of a pipe, and always use the standard invoca To capture a specific value from a JSON object, you just list the key after the `.`: ``` -$ bitcoin-cli signrawtransaction $rawtxhex | jq -r '.hex' +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' 0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` With that tool in hand, you can capture information from JSON objects to command-line variables: ``` -$ signedtx=$(bitcoin-cli signrawtransaction $rawtxhex | jq -r '.hex') +$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') $ echo $signedtx 0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` You can then use those variables easily and without error: ``` -$ bitcoin-cli sendrawtransaction $signedtx +$ bitcoin-cli sendrawtransactionwithwallet $signedtx 3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 ``` ## Use JQ to Access Single JSON Object Values in an Array by Key From 241ac9157a739c7ae28ad7f3176814df3dee232b Mon Sep 17 00:00:00 2001 From: Perry Smit Date: Tue, 16 Jun 2020 09:11:45 +0200 Subject: [PATCH 003/202] Update 02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md When you are on ubuntu 18.04 you should add the aliases in ~/.bash_aliases --- 02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md index b0d5a4f..25100bd 100644 --- a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md +++ b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md @@ -258,7 +258,7 @@ You're now ready to get to the bitcoin-specific part of this tutorial! We find a number of Bash aliases helpful to make it easier to use Bitcoin. ``` -$ sudo -u user1 cat >> ~user1/.bash_profile <> ~user1/.bash_aliases < Date: Tue, 16 Jun 2020 10:01:35 +0200 Subject: [PATCH 004/202] Update 03_4_Receiving_a_Transaction.md Should getrawtransaction not be gettransaction? Did not work for me otherwise. --- 03_4_Receiving_a_Transaction.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/03_4_Receiving_a_Transaction.md b/03_4_Receiving_a_Transaction.md index b88ae54..2f01b70 100644 --- a/03_4_Receiving_a_Transaction.md +++ b/03_4_Receiving_a_Transaction.md @@ -128,7 +128,8 @@ $ bitcoin-cli getrawtransaction "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d8 010000000133261a25b44689bab2c6a207381ca21d243de9bbf21f0fa40c3a26ba7282a87b000000006b483045022100a2640761810dfc34dabed599928243afe24e13f520f780ceb382843a530a577c022050b92f5d9843d70ddb60a0aa294938862f2b7372818d6149ffd4f6adec5cf6c80121034dcaa515c2fda0f4a50b90a6d798e01c00a870bef0bd97154066fe202d2b5d75feffffff02c029cd02000000001976a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac17791703000000001976a914e176ee39c642344df2180863e27e2e936307273c88ac07a41000 ``` Granted, this isn't super useful, because it's the hex-encoded transaction data. Fortunately, you can get a more verbose description just by adding a '1' to your command: -``` +#This didn work for me. I ended by using the command gettransaction instead getrawtransaction. +`` $ bitcoin-cli getrawtransaction "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2" 1 { "hex": "010000000133261a25b44689bab2c6a207381ca21d243de9bbf21f0fa40c3a26ba7282a87b000000006b483045022100a2640761810dfc34dabed599928243afe24e13f520f780ceb382843a530a577c022050b92f5d9843d70ddb60a0aa294938862f2b7372818d6149ffd4f6adec5cf6c80121034dcaa515c2fda0f4a50b90a6d798e01c00a870bef0bd97154066fe202d2b5d75feffffff02c029cd02000000001976a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac17791703000000001976a914e176ee39c642344df2180863e27e2e936307273c88ac07a41000", From 38c0403d711d8fd6fc7d89b826f3c043a734861b Mon Sep 17 00:00:00 2001 From: Perry Smit Date: Tue, 16 Jun 2020 15:09:47 +0200 Subject: [PATCH 005/202] Update 06_5_Sending_a_Transaction_with_Data.md error in transaction command --- 06_5_Sending_a_Transaction_with_Data.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/06_5_Sending_a_Transaction_with_Data.md b/06_5_Sending_a_Transaction_with_Data.md index ee7088b..8c0a590 100644 --- a/06_5_Sending_a_Transaction_with_Data.md +++ b/06_5_Sending_a_Transaction_with_Data.md @@ -44,7 +44,8 @@ $ changeaddress=$(bitcoin-cli getrawchangeaddress) You can now write a new rawtransaction with two outputs: one is your change address to get back (most of) your money, the other is a data address, which is the `bitcoin-cli` term for an OP_RETURN. ``` $ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "data": "'$op_return_data'", "'$changeaddress'": 0.8995 }''') -``` +```#this end in an error: Error parsing JSON:{ "data": "transactie + Here's what that transaction actually looks like: ``` From 92750cf8947ae649bb6d0a96a9d1de4fbb371faf Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 08:31:58 -1000 Subject: [PATCH 006/202] btctxfee clarification Clarification per helpful suggestion by @Goosie --- 04_5_Sending_Coins_with_Automated_Raw_Transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md index aad0b8d..22ccdd9 100644 --- a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -98,7 +98,7 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 ] } ``` -We saw the fee in the more extensive output, before we saved the hex to a variable with JQ, but you can verify it with the `btctxfee` JQ alias: +We saw the fee in the more extensive output, before we saved the hex to a variable with JQ, but you can verify it with the `btctxfee` JQ alias created in the [JQ Interlude](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_2__Interlude_Using_JQ.md): ``` $ btctxfee $rawtxhex3 .00023 From 48e4b0ab824d299ba0872106c4639a7c49b97524 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 08:56:16 -1000 Subject: [PATCH 007/202] Verified Debian 10 scripting --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index fe5ea8d..c7fc44e 100644 --- a/TODO.md +++ b/TODO.md @@ -8,7 +8,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 1. Fix Verification errors in Bitcoin Standup Scripts **6/10** * Fix IPADDR error in Bitcoin Standup Scripts **6/10** -2. Upgrade Bitcoin Standup Scripts to Debian 10 +2. Upgrade Bitcoin Standup Scripts to Debian 10 **6/16** 3. Upgrade Bitcoin Standup Scripts to Bitcoin 0.20 4. Ensure Bitcoin Standup covers everything else in previous scripts 5. Rewrite the StackScript chapter From f085893bcb9e4e367bdb5eba2794928d2f29d400 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 09:45:47 -1000 Subject: [PATCH 008/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index c7fc44e..e678a61 100644 --- a/TODO.md +++ b/TODO.md @@ -10,7 +10,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Fix IPADDR error in Bitcoin Standup Scripts **6/10** 2. Upgrade Bitcoin Standup Scripts to Debian 10 **6/16** 3. Upgrade Bitcoin Standup Scripts to Bitcoin 0.20 -4. Ensure Bitcoin Standup covers everything else in previous scripts +4. Ensure Bitcoin Standup covers everything else in previous scripts **6/16** 5. Rewrite the StackScript chapter 6. Rewrite the "by-hand" chapter to match Bitcoin Standup 7. Reintroduce aliases after setup From 8a7f99d28aab4258a137d09c8050bde273d32429 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:10:10 -1000 Subject: [PATCH 009/202] Fully upgraded to integrate with the Linode Standup (Rather than forcing us to maintain two very similar scripts) --- ..._Up_a_Bitcoin-Core_VPS_with_StackScript.md | 203 ++++++++---------- 1 file changed, 90 insertions(+), 113 deletions(-) diff --git a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md index 23079b1..e18ce2c 100644 --- a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md +++ b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -1,10 +1,10 @@ -# 2.2: Setting Up a Bitcoin-Core VPS with StackScript +# 2.2: Setting Up a Bitcoin-Core VPS with Bitcoin StandUp > :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. -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. You just need to enter a few commands and boot your VPS. Then, after you go and get yourself an espresso, you'll be able to come back and 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 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. I’ve also found it useful to be able to use an iPhone or iPad to communicate via SSH to my VPS to do some simple bitcoin tasks. But a higher level of safety is required for significant funds. +> :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. If you want to instead do all the setup by hand, please read the parallel HOWTO file, [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). @@ -40,119 +40,112 @@ Your server security won't be complete if people can break into your Linode acco ### Load the StackScript -There's a copy of our Bitcoin VPS Setup StackScript in [the repo here](02_2__Script_Linode_Setup.stackscript). 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 [Manage StackScripts](https://manager.linode.com/stackscripts/index), or clicking the link under your list of Linodes. Click "Add a new StackScript", give it a good name (we use `Bitcoin VPS Setup`), then copy and paste the script. +Download the [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) from the [Bitcoin Standup Scripts report](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. -### Add a Linode +### Do the Initial Setup -You'll next need to click to your Linodes tab and select "Add a Linode". +You're now ready to create a node based on the Stackscript. -A Linode 2G will suffice for most setups, including: Pruned Mainnet, Pruned Testnet, and even non-Pruned Testnet. They all use less than 50G of storage and they can barely get by with 2G of memory. This is the setup we suggest. - -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 120G, which is currently the Linode 12288, which has 192G of storage and 12G of memory and costs approximately $80 per month. We do _not_ suggest this. - -The following chart shows minimum requirements - -| Setup | Memory | Storage | Linnode | -|-------|--------|---------|---------| -| Mainnet | 2G | 120G | Linode 8GB | -| Pruned Mainnet | 2G | ~5G | Linode 2GB | -| Testnet | 2G | ~15G | Linode 2GB | -| Pruned Testnet | 2G | ~5G | Linode 2GB | -| Regtest | 2G | ~ | Linode 2GB | - -Just choose your Linode type, choose a Location that's geographically as close to you as possible, and click "Add your Linode!". - -> :warning: **WARNING:** We've occasionally had machines run out of memory after running `bitcoind` for a few days when they only had 2G. Coming back, we find that `bitcoind` has stopped, leaving the message "Error: Out of memory. Terminating." in the `debug.log` file. This simply requires a restart of `bitcoind` and ten or fifteen minutes to get the blockchain resynced. This problem has seemed more prevelant starting with our upgrade to 0.18 (after largely going away), so it's possible you'll need to upgrade to the 4G machines solely due to memory issues. - -_Be aware that the requirements might change over time as the blockchain continues to grow. Watch for "Out of Memory" or "Disk Space is Low!" errors. Either one indicates that you should migrate to the next larger machine!_ - -### Configure Your Linode - -You should now be back on your list of Linodes page, with your VPS listed with a status of "Brand New". - -Click on this new Linode to go to its Dashboard. - -You will see that no disks are installed yet. - -Make sure that Lindeo has completed the initial configuration, which just takes a minute or two. Just look for "Linode Initial Configuration" in the "Host Job Queue" and ensure that it has a little green "Success" buttton. - -### Run the StackScript - -You're now ready to run your StackScript! - -Click on "Deploy an Image" then chooose "Deploying using StackScripts". - -If you already added the StackScript to your account, it should be on the list of "Your StackScripts"; select it. - -### Enter Stackscript Options - -To make sure that you can set up your VPS to your specifications, the StackScript has a few options. Here's what you should enter into them. - -_This setup may not work if you do not enter all of this mandatory information:_ - -**Installation Type.** See _Appendix I_ for more on these Bitcoin installation types. If you're planning to get on the main Bitcoin network, you'll probably want to choose "Pruned Mainnet". If you're wanting to play with Bitcoin Core and learn more about how it works, you'll probably want to choose "Unpruned Testnet". - -**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". - -**User Password.** Bitcoin will be setup in an account called "user1". This is the password for that account. - -_You can freely choose to enter this optional information or skip it:_ - -**SSH Key.** Copy your local computer's SSH key here; this allows you be able to automatically login in via SSH to your user1 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. +1. On the [Stackscripts page](https://cloud.linode.com/stackscripts?type=account), click on the "..." to the right of your new script and choose "Deploy New Linode". +2. Fill in a short and fully qualified hostname + * **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 "Pruned Testnet" if you're just playing around. See the [Appendix](#Appendix) for more information on these options. +5. Fill in any other 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. + * **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. *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. +### 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. + +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 | +|-------|--------|---------|---------| +| Mainnet | 2G | 120G | Linode 16GB | +| Pruned Mainnet | 2G | ~5G | Linode 4GB | +| Testnet | 2G | ~15G | Linode 4GB | +| Pruned Testnet | 2G | ~5G | Linode 4GB | +| Regtest | 2G | ~ | Linode 4GB | + +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. 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. + +Just choose your Linode type, choose a Location that's geographically as close to you as possible, and click "Add your Linode!". + +### Do the Final Setup + +The last thing you need to do is enter a root password, then click create. (If you missed anything, you'll be told so now!) + + +**Installation Type.** See _Appendix I_ for more on these Bitcoin installation types. If you're planning to get on the main Bitcoin network, you'll probably want to choose "Pruned Mainnet". If you're wanting to play with Bitcoin Core and learn more about how it works, you'll probably want to choose "Unpruned Testnet". + + Click "Deploy" to initialize your disks and to prepare your VPS. The whole queue should run in less than a minute. When it's done you should see in the "Host Job Queue", green "Success" buttons stating "Disk Create from StackScript - Setting password for root… done." and "Create Filesystem - 256MB Swap Image". You may now want to change your Linode VPS's name from the default `linodexxxxxxxx`. Go to the Settings tab, and change the label to be more useful, such as your VPS's short hostname. For instance I have renamed mine to `bitcoin-testnet-pruned` to differentiate it from other VPSs in my account. -## Boot Your VPS +## Login to Your VPS -Your Linode VPS is now ready to boot. If you are not at your new VPS's Dashboard, click on it. - -Now select the button "Boot". As soon as you see the green button "Success: System Boot" you can login. +If you watch your Linode control panel, you should see the new computer spin up. When the job has reached 100%, you'll be able to login. First, you'll need the IP address. Click on the "Linodes" tab and you should see a listing of your VPS, the fact that it's running, its "plan", its IP address, and some other information. Go to your local console and login to the user1 account using that address: ``` -ssh user1@[IP-ADDRESS] +ssh standup@[IP-ADDRESS] ``` For example: ``` -ssh user1@192.168.33.11 +ssh standup@192.168.33.11 ``` If you configured your VPS to use an SSH key, the login should be automatic (possibly requiring your SSH password to unlock your key). If you didn't configure a SSH key, then you'll need to type in the user1 password. -### Get an Espresso +### Wait a Few Minutes -Here's the big catch: _your StackScript is running right now_. The BASH script gets executed the first time the VPS is booted. That means your VPS isn't ready yet. +Here's a little catch: _your StackScript is running right now_. The BASH script gets executed the first time the VPS is booted. That means your VPS isn't ready yet. -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. +In past versions, this has taken a bit of time, but the Standup script seems to finish in 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/stackscript.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 ~root/standup.log` which will display the current progress of installation, as described in the next section. ## Verify Your Installation -You will know the StackScripts are done when a BITCOIN-IS-READY file appears in the user1 home directory. At that point, your home directory should look like this: +You'll know that stackscrpit is done when the `standup.log` says something like the following: +``` +/root/StackScript - Bitcoin is setup as a service and will automatically start if your VPS reboots and so is Tor +/root/StackScript - You can manually stop Bitcoin with: sudo systemctl stop bitcoind.service +/root/StackScript - You can manually start Bitcoin with: sudo systemctl start bitcoind.service +``` +At that point, your home directory should look like this: ``` -$ ls -bitcoin-0.18.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc -BITCOIN-IS-READY SHA256SUMS.asc +~$ ls +bitcoin-0.20.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc SHA256SUMS.asc ``` -Alongside the BITCOIN-IS-READY file 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: +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: ``` $ rm * @@ -163,17 +156,16 @@ $ 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/stackscript.log +$ sudo grep VERIFICATION ~root/standup.log ``` If you see something like the following, all should be well: ``` -VERIFICATION SUCCESS / SIG: gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) <laanwj@gmail.com>" -VERIFICATION SUCCESS / SHA: 29215a7fe7430224da52fc257686d2d387546eb8acd573a949128696e8761149 +/root/StackScript - VERIFICATION SUCCESS / SIG: gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) " [unknown] +/root/StackScript - VERIFICATION SUCCESS / SHA: 35ec10f87b6bc1e44fd9cd1157e5dfa4``` ``` - -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. 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!_ +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 this script.) 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 @@ -181,13 +173,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/stackscript.log` +`$ sudo more ~root/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/stackscript.err` +`$ sudo more ~root/standup.err` It still has a fair amount of information that isn't errors, but it's a quicker read. @@ -195,33 +187,15 @@ If all look good, congratulations, you have a functioning Bitcoin node using Lin ## What We Have Wrought -Although the default Debian 8 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 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: -### Protected Services +### Protect Services -Your Bitcoin VPS installation is minimal and allows almost no communication. This is managed through Part 3 of the StackScript, which blocks access to most of the ports on the VPS. +Your Bitcoin VPS installation is minimal and allows almost no communication. This is managed through Part 5 of the StackScript, which sets up Tor and ensures that it's the only way to speak with the Bitcoin ports, other than localhost connections. It's further supplement by the uncomplicated firewall (`ufw`), which blocks everything except SSH connections. -Two files control these restrictions, one for IPv4 and one for IPv6: +You should probably leave things like this! You don't want to use a Bitcoin machine for other services, because everyone increases your vulnerability! -``` -/etc/iptables.firewall.rules -/etc/ip6tables.firewall.rules -``` - -If you look at the rules, you'll see they allow all outbound traffic and all local loopback traffic. However, for inbound traffic, the only connections accepted are Bitcoin, Ping, and SSH. If you want to accept other types of traffic, you will need to open up additional ports ("dports") using the same methodology as shown in the Bitcoin port 8333 connection. For example, to allow connections to port 25 (mail), would require adding the following to the iptables and the ip6tables: - -``` --A INPUT -p tcp --dport 25 -j ACCEPT --A INPUT -p udp --dport 25 -j ACCEPT -``` - -This example opens up access to port 25 for TCP and UDP connections. Other popular ports are 80 (HTTP), 443 (HTTPS), 53 (DNS), 110 (POP), and 143 (IMAP). Be sure any such changes are put above the logs and defaults that appear at the end of the iptables.firewall.rules files. - -You can immediately incorporate your changes by running the following script: - -``` -$ /etc/network/if-pre-up.d/firewall -``` +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. It's, as advertised, uncomplicated. For example adding mail services would just require opening the mail port: `sudo ufw allow 25`. But don't do that. ### Protected Shells @@ -247,15 +221,18 @@ echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean false" So now you probably want to play with Bitcoin! -But wait, your Bitcoin daemon is probably still downloading blocks. This alias, from your .bash configuration will tell you how things are going: +But wait, your Bitcoin daemon is probably still downloading blocks. This alias, from your .bash configuration will tell you how things are going. +The `bitcoin-cli getblockcount` will tell you how you're currently doing: ``` -$ btcblock +$ bitcoin-cli getblockcount +1771352 ``` +If it's different every time you type the command, you need to wait before working with Bitcoin. This typically takes 1-6 hours currently fora pruned setup, depending on your precise machine. -If you choose one of the pruned options, it'll probably take a day to download everything. +But, once it settles at a number, you're ready to continue! -So, it might be time for a few more espressos. But soon enough, your system will be ready to go, and you'll be read to start experimenting. +Still, it might be time for a few more espressos. But soon enough, your system will be ready to go, and you'll be read to start experimenting. ## Summary: Setting Up a Bitcoin-Core VPS by Hand @@ -265,7 +242,7 @@ Creating a Bitcoin-Core VPS with a StackScript made the whole process quick, sim You have a few options for what's next: - * Read the [StackScript](02_2__Script_Linode_Setup.stackscript) to understand your setup. + * Read the [StackScript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) to understand your setup. * See the other method for setting up a VPS in [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). * Choose an entirely alternate methodology in [§2.3: Setting Up a Bitcoin-Core Machine via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md). * Move on to "bitcoin-cli" with [Chapter Three: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md). From ee08e59f3b4d5cfa6955d00f15befcc05fa331a1 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:14:17 -1000 Subject: [PATCH 010/202] Delete 02_2__Script_Linode_Setup.stackscript Now fully using Standup --- 02_2__Script_Linode_Setup.stackscript | 358 -------------------------- 1 file changed, 358 deletions(-) delete mode 100644 02_2__Script_Linode_Setup.stackscript diff --git a/02_2__Script_Linode_Setup.stackscript b/02_2__Script_Linode_Setup.stackscript deleted file mode 100644 index dbcaa00..0000000 --- a/02_2__Script_Linode_Setup.stackscript +++ /dev/null @@ -1,358 +0,0 @@ -#!/bin/bash - -# This block defines the variables the user of the script needs to input -# when deploying using this script. -# -# -# BTCTYPE= -# -# HOSTNAME= -# -# FQDN= -# -# USERPASSWORD= -# -# SSH_KEY= -# -# SYS_SSH_IP= - -#### -# 0. Set Initial Variables -#### - -# CURRENT BITCOIN RELEASE: -# Change as necessary - -export BITCOIN=bitcoin-core-0.18.0 - -# Set the variable $IPADDR to the IP address the new Linode receives. -IPADDR=$(/sbin/ifconfig eth0 | awk '/inet / { print $2 }' | sed 's/addr://') - -# Output stdout and stderr to ~root files - -exec > >(tee -a /root/stackscript.log) 2> >(tee -a /root/stackscript.log /root/stackscript.err >&2) - -echo "$0 - BEGINNING NEW MACHINE SETUP STACKSCRIPT" -echo "$0 - BITCOIN SETUP TYPE IS: $BTCTYPE" - -#### -# 1. Update Hostname -#### - -echo $HOSTNAME > /etc/hostname -# /etc/init.d/hostname.sh start -/bin/hostname $HOSTNAME - -echo "$0 - Set hostname as $FQDN ($IPADDR)" -echo "$0 - TODO: Put $FQDN with IP $IPADDR in your main DNS file." - -# Add localhost aliases - -echo "127.0.0.1 localhost" > /etc/hosts -echo "127.0.1.1 $FQDN $HOSTNAME" >> /etc/hosts - -echo "$0 - Set localhost" - -#### -# 2. Update Timezone -#### - -# Set Timezone to America/LA - -TIMEZONE="America/Los_Angeles" -echo $TIMEZONE > /etc/timezone -cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime - -echo "$0 - Set Time Zone to Lost Angeles" - -#### -# 3. Protect the Server -#### - -# Add firewall rules to block everything that's not Bitcoin, Ping, or SSH - -cat > /etc/iptables.firewall.rules < /etc/ip6tables.firewall.rules - -# Make a startup file that runs IPv4 and IPv6 rules - -cat > /etc/network/if-pre-up.d/firewall <> /etc/hosts.allow - echo "sshd: ALL" >> /etc/hosts.deny - echo "$0 - Limited SSH access." - -else - - echo "$0 - WARNING: Your SSH access is not limited; this is a major security hole!" - -fi - -# Block SSH access from everywhere else - -# Yes, this means that if you don't have an IP address for SSH, you can only login -# from Linode's Lish Console - - - -#### -# 4. Set Up User -#### - -# Create "user1" with optional password and give them sudo capability - -/usr/sbin/useradd -m -p `perl -e 'printf("%s\n",crypt($ARGV[0],"password"))' "$USERPASSWORD"` -g sudo -s /bin/bash user1 -/usr/sbin/adduser user1 sudo - -echo "$0 - Setup user1 with sudo access." - -# Set up SSH Key - -if [ -n "$SSH_KEY" ]; then - - mkdir ~user1/.ssh - echo "$SSH_KEY" >> ~user1/.ssh/authorized_keys - chown -R user1 ~user1/.ssh - - echo "$0 - Added .ssh key to user1." - -fi - -# Give user some helpful bitcoin aliases - -if [ "$BTCTYPE" == "Testnet" ] || [ "$BTCTYPE" == "Pruned Testnet" ]; then - -sudo -u user1 cat >> ~user1/.bash_profile <> ~user1/.bash_profile <&1 | grep "Good signature"` -echo "SHASIG is $SHASIG" - -if [[ $SHASIG ]]; then - echo "VERIFICATION SUCCESS / SIG: $SHASIG" -else - (>&2 echo "VERIFICATION ERROR: Signature for Bitcoin did not verify!") -fi - -# Verify Bitcoin: SHA - -export TARSHA256=`/usr/bin/sha256sum ~user1/$BITCOINPLAIN-x86_64-linux-gnu.tar.gz | awk '{print $1}'` -export EXPECTEDSHA256=`cat ~user1/SHA256SUMS.asc | grep $BITCOINPLAIN-x86_64-linux-gnu.tar.gz | awk '{print $1}'` - -if [ "$TARSHA256" == "$EXPECTEDSHA256" ]; then - echo "VERIFICATION SUCCESS / SHA: $TARSHA256" -else - (>&2 echo "VERIFICATION ERROR: SHA for Bitcoin did not match!") -fi - -# Install Bitcoin - -echo "$0 - Installinging Bitcoin." - -sudo -u user1 /bin/tar xzf ~user1/$BITCOINPLAIN-x86_64-linux-gnu.tar.gz -C ~user1 -/usr/bin/install -m 0755 -o root -g root -t /usr/local/bin ~user1/$BITCOINPLAIN/bin/* -/bin/rm -rf ~user1/$BITCOINPLAIN/ - -# Start Up Bitcoin - -echo "$0 - Starting Bitcoin." - -sudo -u user1 /bin/mkdir ~user1/.bitcoin - -# The only variation between Mainnet and Testnet is that Testnet has the "testnet=1" variable -# The only variation between Regular and Pruned is that Pruned has the "prune=550" variable, which is the smallest possible prune - -# TODO: need to test rpcpassword random below using EOF technique -# TODO: there are other more modern ways to set up rpc authentication — to investigate and document. - -cat >> ~user1/.bitcoin/bitcoin.conf << EOF -server=1 -dbcache=1536 -par=1 -blocksonly=1 -maxuploadtarget=137 -maxconnections=16 -rpcuser=bitcoinrpc -rpcpassword=$(xxd -l 16 -p /dev/urandom) -rpcallowip=127.0.0.1 -walletbroadcast=1 -EOF - -if [ "$BTCTYPE" == "Mainnet" ]; then - -cat >> ~user1/.bitcoin/bitcoin.conf << EOF -txindex=1 -EOF - -elif [ "$BTCTYPE" == "Pruned Mainnet" ]; then - -cat >> ~user1/.bitcoin/bitcoin.conf << EOF -prune=550 -EOF - -elif [ "$BTCTYPE" == "Testnet" ]; then - -cat >> ~user1/.bitcoin/bitcoin.conf << EOF -txindex=1 -testnet=1 -EOF - -elif [ "$BTCTYPE" == "Pruned Testnet" ]; then - -cat >> ~user1/.bitcoin/bitcoin.conf << EOF -prune=550 -testnet=1 -EOF - -elif [ "$BTCTYPE" == "Private Regtest" ]; then - - (>&2 echo "$0 - ERROR: Private Regtest is not setup yet.") - -else - - (>&2 echo "$0 - ERROR: Somehow you managed to select no Bitcoin Installation Type, so Bitcoin hasn't been properly setup. Whoops!") - -fi - -/bin/chown user1 ~user1/.bitcoin/bitcoin.conf -/bin/chmod 600 ~user1/.bitcoin/bitcoin.conf - -sudo -u user1 /usr/local/bin/bitcoind -daemon - -# Add Bitcoin Startup to Crontab for User1 - -sudo -u user1 sh -c '( /usr/bin/crontab -l -u user1 2>/dev/null; echo "@reboot /usr/local/bin/bitcoind -daemon" ) | /usr/bin/crontab -u user1 -' - -# Alert User! - -sudo -u user1 touch ~user1/BITCOIN-IS-READY - -echo "$0 - ENDING NEW MACHINE SETUP STACKSCRIPT" From 50fa273757c9955274feb9aa5083c4935632976a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:15:23 -1000 Subject: [PATCH 011/202] Standup updates --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 9c65038..c87a841 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [1.0: Introducing Bitcoin](01_0_Introducing_Bitcoin.md) * [2.0: Setting Up a Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) * [2.1: Setting Up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) - * [2.2: Setting Up a Bitcoin-Core VPS with StackScript.md](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) - * [Linode_Bitcoin-Core_VPS_Setup.stackscript](02_2__Script_Linode_Setup.stackscript) + * [2.2: Setting Up a Bitcoin-Core VPS with Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) * [2.3: Setting Up a Bitcoin-Core Machine via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md) ### PART TWO: BITCOIN-CLI From 090704b9c95fd1db5867fa44c553e01b227b3a14 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:15:55 -1000 Subject: [PATCH 012/202] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c87a841..4148061 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [1.0: Introducing Bitcoin](01_0_Introducing_Bitcoin.md) * [2.0: Setting Up a Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) * [2.1: Setting Up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) - * [2.2: Setting Up a Bitcoin-Core VPS with Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [2.2: Setting Up a Bitcoin-Core VPS with Bitcoin Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) * [2.3: Setting Up a Bitcoin-Core Machine via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md) ### PART TWO: BITCOIN-CLI From c47e81bd4b14a62bf841299d514d41f2d1a62162 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:16:23 -1000 Subject: [PATCH 013/202] No camelcase in standup --- 02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md index e18ce2c..9b59e9a 100644 --- a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md +++ b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -1,4 +1,4 @@ -# 2.2: Setting Up a Bitcoin-Core VPS with Bitcoin StandUp +# 2.2: Setting Up a Bitcoin-Core VPS with Bitcoin Standup > :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. From db25bb097f29b7a072df4282b951f1d1b15b0e79 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:17:00 -1000 Subject: [PATCH 014/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index e678a61..54738a8 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 2. Upgrade Bitcoin Standup Scripts to Debian 10 **6/16** 3. Upgrade Bitcoin Standup Scripts to Bitcoin 0.20 4. Ensure Bitcoin Standup covers everything else in previous scripts **6/16** -5. Rewrite the StackScript chapter +5. Rewrite the StackScript chapter **6/16** 6. Rewrite the "by-hand" chapter to match Bitcoin Standup 7. Reintroduce aliases after setup 8. Figure out what to do about the old `btcblock` on testnet, where there seems to be no CLI way to determine blockheight. From 08bf33d46191fd452b411c94e7cfb4a9ccd7f9f8 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:20:13 -1000 Subject: [PATCH 015/202] Checked off 0.20.0 switchover --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 54738a8..56de676 100644 --- a/TODO.md +++ b/TODO.md @@ -9,7 +9,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 1. Fix Verification errors in Bitcoin Standup Scripts **6/10** * Fix IPADDR error in Bitcoin Standup Scripts **6/10** 2. Upgrade Bitcoin Standup Scripts to Debian 10 **6/16** -3. Upgrade Bitcoin Standup Scripts to Bitcoin 0.20 +3. Upgrade Bitcoin Standup Scripts to Bitcoin 0.20 **6/16** 4. Ensure Bitcoin Standup covers everything else in previous scripts **6/16** 5. Rewrite the StackScript chapter **6/16** 6. Rewrite the "by-hand" chapter to match Bitcoin Standup From dd1545a267129441311faab97a85d3fe66dca4b9 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:27:04 -1000 Subject: [PATCH 016/202] Adding Tor Link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4148061..17767bf 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ _This tutorial assumes that you have some minimal background of how to use the c _The section is currently unwritten._ -* 12.0: Setting Up Tor +* [12.0: Using Tor](12_0_Using_Tor.md) * 12.1: Verifying Your Tor Setup * 12.2: Changing Your Bitcoin Hidden Services * 12.3: Adding SSH Hiddne Services From 02f41029a094dbdd01f8ae83a45a6aba42854546 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:29:55 -1000 Subject: [PATCH 017/202] Create 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 12_0_Using_Tor.md diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md new file mode 100644 index 0000000..864a2e4 --- /dev/null +++ b/12_0_Using_Tor.md @@ -0,0 +1,9 @@ +# Chapter 12: Using Tor + +_This is currently a placeholder; Writing it in Task #15 on the current [TODO list](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/TODO.md). + +This section will talk about using the Tor services that are now available courtesy of Bitcoin Standup._) + + * 12.1: Verifying Your Tor Setup + * 12.2: Changing Your Bitcoin Hidden Services + * 12.3: Adding SSH Hiddne Services From 09594155329187ad0bee7a444d37c5ba0158f031 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:32:08 -1000 Subject: [PATCH 018/202] Added link to future Tor chapter --- 02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md index 9b59e9a..b9e8cd4 100644 --- a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md +++ b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -189,13 +189,13 @@ If all look good, congratulations, you have a functioning Bitcoin node using Lin 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: -### Protect Services +### Protected Services Your Bitcoin VPS installation is minimal and allows almost no communication. This is managed through Part 5 of the StackScript, which sets up Tor and ensures that it's the only way to speak with the Bitcoin ports, other than localhost connections. It's further supplement by the uncomplicated firewall (`ufw`), which blocks everything except SSH connections. -You should probably leave things like this! You don't want to use a Bitcoin machine for other services, because everyone increases your vulnerability! +**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. -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. It's, as advertised, uncomplicated. 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. It's, as advertised, uncomplicated. For example adding mail services would just require opening the mail port: `sudo ufw allow 25`. But don't do that. ### Protected Shells From c98403c8e1eab3b5a0784242a498245dfba937af Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 11:33:33 -1000 Subject: [PATCH 019/202] Update 02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md --- 02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md index 25100bd..1787fb1 100644 --- a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md +++ b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md @@ -6,7 +6,9 @@ This document explains how to set up a VPS (Virtual Private Server) by hand to r > :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. I’ve also found it useful to be able to use an iPhone or iPad to communicate via SSH to my VPS to do some simple bitcoin tasks. But a higher level of safety is required for significant funds. -If you want to instead have a script do the setup for you, specifically at linode.com, read the parallel HOWTO file, [§2.2: Setting up a Bitcoin-Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). +If you want to instead have a script do the setup for you, specifically at linode.com, read the parallel HOWTO file, [§2.2: Setting up a Bitcoin-Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). This + +> :warning: **WARNING:** This chapter is currently out of sync with the Bitcoin Standup script, and won't be updated until we finish some changes to Standup this summer. We very much suggest using the Script instead of this by-hand description, because it includes Tor and other security functions. If you already have a Bitcoin node running, instead read the next HOWTO file, [Chapter Three: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md). From 27bf4743a6bbd7cfbb9f27615d94311db16d6136 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 16 Jun 2020 20:22:11 -1000 Subject: [PATCH 020/202] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17767bf..06cc30f 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ Additional contributions are listed below: | Role | Names | | ------------------- | ---------------------------------------- | -| ***Contributors:*** | | +| ***Contributors:*** | [jodobear](https://github.com/jodobear) (Appendix I) | | ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) | | ***Sponsors:*** | Blockstream Corporation | From bf12843d24ce261b9b307daef3a89bcbdd013114 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 18 Jun 2020 09:03:02 +1000 Subject: [PATCH 021/202] Fixed existing sections of Accessing_Bitcoind_with_NodeJS --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 49 ++++++++++++++++++-------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index e536aab..80d01fc 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -7,35 +7,40 @@ BCRPC is built on node.js. Thus, you'll first need to install the `node.js` and `npm` (node package manager) packages for your system. If you're using a Ubuntu machine, you can run the following commands to get a new version of `node.js` (as opposed to the horribly out-of-date version in the Ubuntu package system). -``` -curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - -sudo apt-get install -y nodejs -sudo apt-get install mocha -g -``` -### Set Up BCRPC -Create a new node.js project and install BCRPC via NPM. ``` -$ mkdir myproject -$ cd myproject -$ npm init -[...] -$ npm install --save bcrpc +curl -sL https://deb.nodesource.com/setup_14.x | sudo bash - +sudo apt-get install -y nodejs +sudo npm install mocha -g ``` + ### Test BCRPC -To test the BCRPC package, you must first set environmental variables for your rpcuser and rpcpassword. As noted in [§12.1: Accessing Bitcoind with Curl](12_1_Accessing_Bitcoind_with_Curl.md), these come from `~/.bitcoin/bitcoin.conf`. +Clone the BCRPC package from GitHub and install its dependencies. + +``` +$ git clone https://github.com/dgarage/bcrpc.git +$ cd bcrpc +$ npm install +``` + +To test the BCRPC package, you must first set environmental variables for your rpcuser and rpcpassword. As noted in [§12.1: Accessing Bitcoind with Curl](12_1_Accessing_Bitcoind_with_Curl.md), these come from `~/.bitcoin/bitcoin.conf`. You must also set the RPC port to 18332 which should be correct for the standard testnet setup described in these documents. + ``` $ export BITCOIND_USER=bitcoinrpc $ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c +$ export BITCOIND_PORT=18332 ``` + > **WARNING:** Obviously, you'd never put set your password in an environmental variable in a production environment. +> **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup. You can now verify everything is working correctly: + ``` $ npm test -> bcrpc@0.0.5 test /home/user1/bcrpc-master +> bcrpc@0.2.2 test /home/user1/bcrpc > mocha tests.js BitcoinD @@ -46,7 +51,21 @@ $ npm test 2 passing (36ms) ``` -Congratulations, you now have a Bitcoin-ready RPC wrapper for node.js. + +Congratulations, you now have a Bitcoin-ready RPC wrapper for Node.js working with your Bitcoin setup. + +### Set Up BCRPC + +Leave the BCRPC directory and create a new Node.js project with BCRPC installed via npm. + +``` +$ cd .. +$ mkdir myproject +$ cd myproject +$ npm init + [continue with default options] +$ npm install bcrpc +``` ## Manipulate Your Wallet From 0ddac5f54b7e6f255dff81375649fe3391e98843 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 18 Jun 2020 09:05:57 +1000 Subject: [PATCH 022/202] Fixed typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06cc30f..bd6f387 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ _This section is currently a messy set of older writings which are being reorgan * 18.0: Talking to Bitcoind with Other Languages * [18.1: Accessing Bitcoind with Go] * [18.2: Accessing Bitcoind with Java](18_2_Accessing_Bitcoind_with_Java.md) — Needs Rewrite + Editing - * [18.3: Accessing Bitcoind with_Node_JS](18_3_Accessing_Bitcoind_with_NodeJS.md) — Needs Rewrite + Editing + * [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) — Needs Rewrite + Editing * [18.4: Accessing Bitcoind with Python] * [18.5: Accessing Bitcoind with Rust] * [18.6: Accessing Bitcoind with Swift] From 2c53ed6e768a0c790896d3f027c55d451a1eff1f Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 08:05:58 -1000 Subject: [PATCH 023/202] Expanding checklist for step 9 --- TODO.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 56de676..981f5e1 100644 --- a/TODO.md +++ b/TODO.md @@ -12,14 +12,25 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 3. Upgrade Bitcoin Standup Scripts to Bitcoin 0.20 **6/16** 4. Ensure Bitcoin Standup covers everything else in previous scripts **6/16** 5. Rewrite the StackScript chapter **6/16** -6. Rewrite the "by-hand" chapter to match Bitcoin Standup +6. Rewrite the "by-hand" chapter to match Bitcoin Standup (Pending summer work) 7. Reintroduce aliases after setup 8. Figure out what to do about the old `btcblock` on testnet, where there seems to be no CLI way to determine blockheight. ## 2. Upgrade to 0.20 9. Walk through chapters 1-11, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. - + * Edit Chapter 1 + * Re-edit Chapter 2 + * Check Chapter 3 + * Check Chapter 4 + * Check Chapter 5 + * Check Chapter 6 + * Check Chapter 7 + * Check Chapter 8 + * Check Chapter 9 + * Check Chapter 10 + * Check Chapter 11 + ## 3. Add BTCDEB Support 10. Make all examples in [7.4](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_4_Testing_a_Bitcoin_Script.md) and possibly elsewhere use BTCDeb. From 277ba26e56d6fbb1d8e4fd1bce65da7a2737a0ff Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 08:24:51 -1000 Subject: [PATCH 024/202] revised part names, added appendix 1 --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 06cc30f..a596007 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [2.2: Setting Up a Bitcoin-Core VPS with Bitcoin Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) * [2.3: Setting Up a Bitcoin-Core Machine via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md) -### PART TWO: BITCOIN-CLI +### PART TWO: USING BITCOIN-CLI * [3.0: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md) * [3.1: Verifying Your Bitcoin Setup](03_1_Verifying_Your_Bitcoin_Setup.md) @@ -71,7 +71,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [11.2: Writing Complex Multisig Scripts](11_2_Writing_Complex_Multisig_Scripts.md) * [11.3: Empowering Bitcoin with Scripts](11_3_Empowering_Bitcoin_with_Scripts.md) -### PART FOUR: TOR +### PART FOUR: USING TOR _The section is currently unwritten._ @@ -80,7 +80,7 @@ _The section is currently unwritten._ * 12.2: Changing Your Bitcoin Hidden Services * 12.3: Adding SSH Hiddne Services -### PART FIVE: LIGHTNING-CLI +### PART FIVE: USING LIGHTNING-CLI _This section is unwritten currently, and will probably involve chapter 14.0 expanding into at least two chapters._ @@ -89,7 +89,7 @@ _This section is unwritten currently, and will probably involve chapter 14.0 exp > _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/._ -### PART SIX: BITCOIN & LIGHTNING PROGRAMMING +### PART SIX: PROGRAMMING WITH RPC _This section is currently a messy set of older writings which are being reorganized as listed below. We're not going to work through this section until we've got chapters 1-11 updated per our current notes, then 12-14 written. But, if you'd like to see what we have to date on programming in correlation with Bitcoin Core, please feel free._ @@ -111,9 +111,9 @@ _This section is currently a messy set of older writings which are being reorgan * [18.5: Accessing Bitcoind with Rust] * [18.6: Accessing Bitcoind with Swift] -### APPENDICE +### APPENDICES -* Appendix I: Compiling Bitcoin +* [Appendix I: Compiling Bitcoin from Source](A1_0_Compiling_Bitcoin_from_Source.md) * [Appendix II: Using Bitcoin Regtest](A2_0_Setting_Up_a_Bitcoin_Regtest.md) — Needs Rewrite + Editing * [A2.1: Starting the Regtest](A2_1_Starting_the_Regtest.md) — Needs Rewrite + Editing * [A2.2: Mining with Regtest](A2_2_Mining_with_Regtest.md) — Needs Rewrite + Editing From 923975bdeedc5eba937943c800103a190ee381fe Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 08:25:04 -1000 Subject: [PATCH 025/202] edited & added overview --- 00_0_Introduction.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/00_0_Introduction.md b/00_0_Introduction.md index 8439161..4fc8c8e 100644 --- a/00_0_Introduction.md +++ b/00_0_Introduction.md @@ -4,12 +4,24 @@ The ways that we make payments for goods and services has been changing dramatic These centralization risks were some of the prime catalysts behind the creation of cryptocurrencies, the first and most successful of which is Bitcoin. Bitcoin offers pseudonymity, it makes it difficult to correlate transactions, and it makes censorship by individual entities all but impossible. These advantages have made it one of the quickest growing currencies in the world. That growth in turn has made Bitcoin into a going concern among entrepreneurs and developers, eager to create new services for the Bitcoin community. -If you're one of those entrepreneurs or developers, then this book is for you, because it's all about learning to program Bitcoin. It's an introductory book, which 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. +If you're one of those entrepreneurs or developers, then this book is for you, because it's all about learning to program Bitcoin. It's an introductory book 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 RPG 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``. 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. +## Overview of Topics + +This book is broadly divided into the following sections: + + * **Part One: Preparing for Bitcoin** - Understanding the basics of Bitcoin and setting up a server for use. + * **Part Two: Using Bitcoin-CLI** - Using the Bitcoin-CLI for creating transactions. + * **Part Three: Bitcoin Scripting** - Expanding your Bitcoin work with scripts. + * **Part Four: Using Tor** - Improving your node security with Tor + * **Part Five: Using Lightning-CLI** - Using the Lightning-CLI for creating transactions. + * **Part Six: Programming with RPC** - Accessing RPC from C and other languages. + * **Appendices** - Utilizing less common Bitcoin setups. + ## What's Next? Learn the basics of Bitcoin in [Chapter One: Introducing Bitcoin](01_0_Introducing_Bitcoin.md). From cefea8f4580ba934f58d2acea70a89e5c37ff5a3 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 08:27:51 -1000 Subject: [PATCH 026/202] listed status of all sections --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a596007..d214453 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,16 @@ Learning Bitcoin from the Command Line is a tutorial for working with Bitcoin (a > NOTE: This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for use. -## Table of Contents - _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._ +## Table of Contents + * [0.0: Introduction to Programming with Bitcoin Core and Lightning](00_0_Introduction.md) ### PART ONE: PREPARING FOR BITCOIN +**Status:** Undergoing light editing. Needs to have concepts brought up to 0.20. + * [1.0: Introducing Bitcoin](01_0_Introducing_Bitcoin.md) * [2.0: Setting Up a Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) * [2.1: Setting Up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) @@ -20,6 +22,8 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART TWO: USING BITCOIN-CLI +**Status:** Requires editing; requires check that it works in 0.20; requires concepts brought up to 0.20. + * [3.0: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md) * [3.1: Verifying Your Bitcoin Setup](03_1_Verifying_Your_Bitcoin_Setup.md) * [3.2: Knowing Your Bitcoin Setup](03_2_Knowing_Your_Bitcoin_Setup.md) @@ -48,6 +52,8 @@ _This tutorial assumes that you have some minimal background of how to use the c ## PART THREE: BITCOIN SCRIPTING +**Status:** Requires editing; requires check that it works in 0.20; requires concepts brought up to 0.20. + * [7.0: Introducing Bitcoin Scripts](07_0_Introducing_Bitcoin_Scripts.md) * [7.1: Understanding the Foundation of Transactions](07_1_Understanding_the_Foundation_of_Transactions.md) * [7.2: Running a Bitcoin Script](07_2_Running_a_Bitcoin_Script.md) @@ -73,7 +79,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART FOUR: USING TOR -_The section is currently unwritten._ +**Status:** Unwritten. * [12.0: Using Tor](12_0_Using_Tor.md) * 12.1: Verifying Your Tor Setup @@ -82,7 +88,7 @@ _The section is currently unwritten._ ### PART FIVE: USING LIGHTNING-CLI -_This section is unwritten currently, and will probably involve chapter 14.0 expanding into at least two chapters._ +**Status:** Unwritten. Chapter 14 may expand into multiple chapters. * 13.0: Setting Up Lightning * 14.0: Using Lightning @@ -91,7 +97,7 @@ _This section is unwritten currently, and will probably involve chapter 14.0 exp ### PART SIX: PROGRAMMING WITH RPC -_This section is currently a messy set of older writings which are being reorganized as listed below. We're not going to work through this section until we've got chapters 1-11 updated per our current notes, then 12-14 written. But, if you'd like to see what we have to date on programming in correlation with Bitcoin Core, please feel free._ +**Status:** This section is currently a messy set of older writings which are being reorganized as listed below. We're not going to work through this section until we've got chapters 1-11 updated per our current notes, then 12-14 written. But, if you'd like to see what we have to date on programming in correlation with Bitcoin Core, please feel free. * [15.0: Talking to Bitcoind with C](15_0_Talking_to_Bitcoind.md) — Needs Rewrite + Editing * [15.1: Accessing Bitcoind with C](15_1_Accessing_Bitcoind_with_C.md) — Needs Rewrite @@ -113,6 +119,8 @@ _This section is currently a messy set of older writings which are being reorgan ### APPENDICES +**Status:** Varied. Appendix I is recent that just needs editing for style; Appendix II needs a rewrite. + * [Appendix I: Compiling Bitcoin from Source](A1_0_Compiling_Bitcoin_from_Source.md) * [Appendix II: Using Bitcoin Regtest](A2_0_Setting_Up_a_Bitcoin_Regtest.md) — Needs Rewrite + Editing * [A2.1: Starting the Regtest](A2_1_Starting_the_Regtest.md) — Needs Rewrite + Editing From f7c1ebb2c7889533c62158008c76fe5af770202d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 08:28:42 -1000 Subject: [PATCH 027/202] check: chapter 0 --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 981f5e1..ed64b0c 100644 --- a/TODO.md +++ b/TODO.md @@ -19,6 +19,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip ## 2. Upgrade to 0.20 9. Walk through chapters 1-11, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. + * Edit Chapter 0 **6/19** * Edit Chapter 1 * Re-edit Chapter 2 * Check Chapter 3 From 9827ace4ad5030db12e51217d5567fd77f115ff9 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:01:27 -1000 Subject: [PATCH 028/202] edits, first mention of SegWit --- 01_0_Introducing_Bitcoin.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/01_0_Introducing_Bitcoin.md b/01_0_Introducing_Bitcoin.md index 8c48302..9867c86 100644 --- a/01_0_Introducing_Bitcoin.md +++ b/01_0_Introducing_Bitcoin.md @@ -26,13 +26,13 @@ Obviously, Bitcoin is the heart of this book, but it's also the originator of ma **_Who Can You Send Coins To?_** The vast majority of bitcoin transactions involve coins being sent to individual people (or at least to individual Bitcoin addresses). However, more complex methodologies can be used to send bitcoins to groups of people or to scripts. These various methodologies have names like P2PKH, multisig, and P2SH. -**_How Are Transactions Stored?_** Transactions are combined into larger blocks of data, which are then written to the blockchain ledger. A block is built in such a way that it cannot be replaced or rewritten once several blocks have been built after it. This is what makes bitcoins non-repudiable: the decentralized global ledger where everything is recorded is effectively a permanent and unchangeable database. +**_How Are Transactions Stored?_** Transactions are combined into larger blocks of data, which are then written to the blockchain ledger. A block is built in such a way that it cannot be replaced or rewritten once several blocks have been built atop (following) it. This is what makes bitcoins non-repudiable: the decentralized global ledger where everything is recorded is effectively a permanent and unchangeable database. However, the process of building these blocks is stochastic: it's somewhat random, so you can never be assured that a transaction will be placed in a specific block. There can also be changes in blocks if they're very recent, but only if they're _very_ recent. So, things become non-repudiable (and permanent and unchangeable) after a little bit of time. -**_How Are Transactions Protected?_** The funds contained in a Bitcoin transaction are locked with a cryptographic puzzle. These puzzles are designed so that they can be easily solved by the person who the funds were sent to. This is done using the power of public-key cryptography. +**_How Are Transactions Protected?_** The funds contained in a Bitcoin transaction are locked with a cryptographic puzzle. These puzzles are designed so that they can be easily solved by the person who the funds were sent to. This is done using the power of public-key cryptography. Technically, a transaction is protected by a signature that proves you're the owner of the public key that a transaction was sent to: this proof of ownership is the puzzle that's being solved. -Funds are further protected by the use of hashes. Public keys aren't actually stored in the blockchain, only public-key hashes are. This means that even if quantum computer were to come along, Bitcoin transactions would remain protected by this second level of cryptography. +Funds are further protected by the use of hashes. Public keys aren't actually stored in the blockchain until the funds are spent: only public-key hashes are. This means that even if quantum computer were to come along, Bitcoin transactions would remain protected by this second level of cryptography. **_How Are Transactions Created?_** The heart of each Bitcoin transaction is a FORTH-like scripting language that is used to lock the transaction. To respend the money, the recipient provides specific information to the script that proves he's the intended recipient. @@ -40,7 +40,7 @@ However, these Bitcoin scripts are the lowest level of Bitcoin functionality. Mu ### Bitcoin — In Short -One way to think of Bitcoin is as _a sequence of atomic transactions_. 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 stored as a script. Every transaction is recorded in an immutable global ledger. +One way to think of Bitcoin is as _a sequence of atomic transactions_. 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. Every transaction is recorded in an immutable global ledger. ## About Public-Key Cryptography @@ -50,9 +50,9 @@ It's important to Bitcoin (and to most blockchain systems) because it's the basi **_What Is a Public Key?_** A public key is the key given out to other people. In a typical public-key system, a user generates a public key and a private key, then he gives the public key to all and sundry. Those recipients can encrypt information with the public key, but it can't be decrypted with the same public key because of the asymmetry of the key pair. -**_What Is a Private Key?_** A private key is linked to a public key in a key pair. In a typical public-key system, a user keeps his private key secure and uses it to decrypt messages that were encrypted with his public key in the process of being sent to him.. +**_What Is a Private Key?_** A private key is linked to a public key in a key pair. In a typical public-key system, a user keeps his private key secure and uses it to decrypt messages that were encrypted with his public key before being sent to him. -**_What Is a Signature?_** A message (or more commonly, a hash of a message) can be signed with a private key, creating a signature. Anyone with the corresponding public key can then validate the signature, which verifies that the signer owns the private key associated with the public key in question. +**_What Is a Signature?_** A message (or more commonly, a hash of a message) can be signed with a private key, creating a signature. Anyone with the corresponding public key can then validate the signature, which verifies that the signer owns the private key associated with the public key in question. _SegWit_ is a specific format for storing a signature on the Bitcoin network that we'll meet down the line. **_What Is a Hash Function?_** A hash function is an algorithm frequently used with cryptography. It's a way to map a large, arbitrary amount of data to a small, fixed amount of data. Hash functions used in cryptography are one-way and collision-resistant, meaning that a hash can reliably be linked to the original data, but the original data can not be regenerated from the hash. Hashes thus allow the transmission of small amounts of data to represent large amounts of data, which can be important for efficiency and storage requirements. @@ -88,7 +88,7 @@ One way to think of public-key cryptography is: _a way to enable public-key cryp ## About Blockchains -Blockchain is the generalization of the methodology used by Bitcoin to create a distributed global ledger. Bitcoin is a blockchain as are any number of alt-coins, each of which lives in its networks and writes to its own chain. Sidechains like Liquid are blockchains too. Blockchains don't even need to have anything to do with finances. For example, there have been many discussions of using blockchains to protect self-sovereign identities. +Blockchain is the generalization of the methodology used by Bitcoin to create a distributed global ledger. Bitcoin is a blockchain as are any number of alt-coins, each of which lives on its own networks and writes to its own chain. Sidechains like Liquid are blockchains too. Blockchains don't even need to have anything to do with finances. For example, there have been many discussions of using blockchains to protect self-sovereign identities. Though you need to understand the basics of how a blockchain works to understand how transactions work in Bitcoin, you won't need to go any further than that. Because blockchains have become a wide category of technology, those basic concepts are likely to be applicable to many other projects in this growing technology sector. The specific programming commands learned in this book will not be, however, as they're fairly specific to Bitcoin (and Lightning). From 244fb07464a1ed548964c9275eb0b562fae4f4d6 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:01:53 -1000 Subject: [PATCH 029/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index ed64b0c..c853133 100644 --- a/TODO.md +++ b/TODO.md @@ -20,7 +20,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 9. Walk through chapters 1-11, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. * Edit Chapter 0 **6/19** - * Edit Chapter 1 + * Edit Chapter 1 **6/19** * Re-edit Chapter 2 * Check Chapter 3 * Check Chapter 4 From d69bdf423e778b89875cce6dc27e72c3098b450d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:09:09 -1000 Subject: [PATCH 030/202] clarified path through chapter --- 02_0_Setting_Up_a_Bitcoin-Core_VPS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02_0_Setting_Up_a_Bitcoin-Core_VPS.md b/02_0_Setting_Up_a_Bitcoin-Core_VPS.md index 7850eb2..8b2c10e 100644 --- a/02_0_Setting_Up_a_Bitcoin-Core_VPS.md +++ b/02_0_Setting_Up_a_Bitcoin-Core_VPS.md @@ -1,6 +1,6 @@ # Chapter Two: Creating a Bitcoin-Core VPS -To get started with Bitcoin, you first need to set up a machine running Bitcoin. The articles in this chapter describe how to do so using a VPS (Virtual Private Server). +To get started with Bitcoin, you first need to set up a machine running Bitcoin. The articles in this chapter describe how to do so, primarily by using a VPS (Virtual Private Server). ## Objectives for this Chapter @@ -20,7 +20,7 @@ Supporting objectives include the ability to: ## Table of Contents -You can either create your VPS by hand or you can use a simple StackScript at Linode.com to do so. +You don't actually need to read this entire chapter. Decide if you want to set up your VPS by hand, typing in every command (§2.1); if you want to run a StackScript to set it up on a Linode VPS (§2.2); or you want to set up on a different environment, such as on an AWS machine or a Mac (§2.3). Then, jump to the appropriate section. * [Section One: Setting Up a Bitcoin Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) * [Section Two: Setting Up a Bitcoin Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) From 3b90af403d9b437a81f1cce74f299197f4ae18ae Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:09:46 -1000 Subject: [PATCH 031/202] moved up notice of out-of-date content --- 02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md index 1787fb1..8651069 100644 --- a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md +++ b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md @@ -2,14 +2,14 @@ > :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. +> :information_source: **WARNING:** This chapter is currently out of sync with the Bitcoin Standup script, and won't be updated until we finish some changes to Standup this summer. We very much suggest using the Script instead of this by-hand description, because it includes Tor and other security functions. + This document explains how to set up a VPS (Virtual Private Server) by hand to run a Bitcoin node on a cloud computer. You'll need to set up your computer yourself, but then this document will provide you with important commands to secure your VPS and to get it running Bitcoin. The setup should all be done in my session, so you don't lose the variables `export`ed at the start. > :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. I’ve also found it useful to be able to use an iPhone or iPad to communicate via SSH to my VPS to do some simple bitcoin tasks. But a higher level of safety is required for significant funds. If you want to instead have a script do the setup for you, specifically at linode.com, read the parallel HOWTO file, [§2.2: Setting up a Bitcoin-Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). This -> :warning: **WARNING:** This chapter is currently out of sync with the Bitcoin Standup script, and won't be updated until we finish some changes to Standup this summer. We very much suggest using the Script instead of this by-hand description, because it includes Tor and other security functions. - If you already have a Bitcoin node running, instead read the next HOWTO file, [Chapter Three: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md). ## Choosing Your Bitcoin Setup From fe589d9c9c5714c5323d8415d83ac31baf09aa2a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:10:31 -1000 Subject: [PATCH 032/202] added link to warning --- 02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md index 8651069..b2b6999 100644 --- a/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md +++ b/02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md @@ -2,7 +2,7 @@ > :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. -> :information_source: **WARNING:** This chapter is currently out of sync with the Bitcoin Standup script, and won't be updated until we finish some changes to Standup this summer. We very much suggest using the Script instead of this by-hand description, because it includes Tor and other security functions. +> :information_source: **WARNING:** This chapter is currently out of sync with the Bitcoin Standup script, and won't be updated until we finish some changes to Standup this summer. We very much suggest [using the Script](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) instead of this by-hand description, because it includes Tor and other security functions. This document explains how to set up a VPS (Virtual Private Server) by hand to run a Bitcoin node on a cloud computer. You'll need to set up your computer yourself, but then this document will provide you with important commands to secure your VPS and to get it running Bitcoin. The setup should all be done in my session, so you don't lose the variables `export`ed at the start. From 71820026105811ddc3ec2a7aa0806853bba1b024 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:11:18 -1000 Subject: [PATCH 033/202] =?UTF-8?q?fixed=20=C2=A72.2=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 02_0_Setting_Up_a_Bitcoin-Core_VPS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02_0_Setting_Up_a_Bitcoin-Core_VPS.md b/02_0_Setting_Up_a_Bitcoin-Core_VPS.md index 8b2c10e..1e1271d 100644 --- a/02_0_Setting_Up_a_Bitcoin-Core_VPS.md +++ b/02_0_Setting_Up_a_Bitcoin-Core_VPS.md @@ -23,5 +23,5 @@ Supporting objectives include the ability to: You don't actually need to read this entire chapter. Decide if you want to set up your VPS by hand, typing in every command (§2.1); if you want to run a StackScript to set it up on a Linode VPS (§2.2); or you want to set up on a different environment, such as on an AWS machine or a Mac (§2.3). Then, jump to the appropriate section. * [Section One: Setting Up a Bitcoin Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) - * [Section Two: Setting Up a Bitcoin Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [Section Two: Setting Up a Bitcoin Core VPS with Bitcoin Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) * [Section Three: Setting Up a Bitcoin Core Machine via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md) From 110ac5b1a3d4108ea6774d537df047e94ebfbf1f Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:27:33 -1000 Subject: [PATCH 034/202] better edited for new Standup integration --- ..._Up_a_Bitcoin-Core_VPS_with_StackScript.md | 61 ++++++++----------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md index b9e8cd4..892b9ea 100644 --- a/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md +++ b/02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md @@ -6,9 +6,9 @@ This document explains how to set up a VPS (Virtual Private Sever) to run a Bitc > :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. -If you want to instead do all the setup by hand, please read the parallel HOWTO file, [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). - -If you already have a Bitcoin node running, instead read the next HOWTO file, [Chapter Three: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md). +* If you want to instead do all the setup by hand, goto [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). +* If you want to instead setup on a machine other than a Linode VPS, such as an AWS machine or a Mac, goto [§2.3: Setting Up a Bitcoin-Core via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md) +* If you already have a Bitcoin node running, goto [Chapter Three: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md). ## Getting Started with Linode @@ -30,7 +30,7 @@ https://www.linode.com/?r=23211828bc517e2cb36e0ca81b91cc8c0e1b2d96 You'll need to provide an email address and later preload money from a credit card or PayPal for future costs. -When you're done, you should land on https://manager.linode.com +When you're done, you should land on [https://cloud.linode.com/dashboard](https://cloud.linode.com/dashboard). ### Consider Two-Factor Authentication @@ -40,25 +40,25 @@ 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 report](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 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. ### Do the Initial Setup You're now ready to create a node based on the Stackscript. 1. On the [Stackscripts page](https://cloud.linode.com/stackscripts?type=account), click on the "..." to the right of your new script and choose "Deploy New Linode". -2. Fill in a short and fully qualified hostname - * **Short Hostname.** Pick a name for your VPS. For example, "mybtctest" +2. Fill in a short and a fully qualified hostname + * **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 "Pruned Testnet" if you're just playing around. See the [Appendix](#Appendix) for more information on these options. + * **Installation Type.** This is likely "Mainnet" or "Pruned Mainnet" if you are setting up a node for usage and "Pruned Testnet" if you're just playing around. See the [Appendix](#appendix-bitcoin-installation-types) for more information on these options. 5. Fill in any other 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. * **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). + * **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. *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._ @@ -77,7 +77,7 @@ The following chart shows minimum requirements | Setup | Memory | Storage | Linnode | |-------|--------|---------|---------| -| Mainnet | 2G | 120G | Linode 16GB | +| Mainnet | 2G | 280G | Linode 16GB | | Pruned Mainnet | 2G | ~5G | Linode 4GB | | Testnet | 2G | ~15G | Linode 4GB | | Pruned Testnet | 2G | ~5G | Linode 4GB | @@ -85,22 +85,17 @@ The following chart shows minimum requirements 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. 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. +* 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. -Just choose your Linode type, choose a Location that's geographically as close to you as possible, and click "Add your Linode!". ### Do the Final Setup -The last thing you need to do is enter a root password, then click create. (If you missed anything, you'll be told so now!) - - -**Installation Type.** See _Appendix I_ for more on these Bitcoin installation types. If you're planning to get on the main Bitcoin network, you'll probably want to choose "Pruned Mainnet". If you're wanting to play with Bitcoin Core and learn more about how it works, you'll probably want to choose "Unpruned Testnet". - +The last thing you need to do is enter a root password. (If you missed anything, you'll be told so now!) Click "Deploy" to initialize your disks and to prepare your VPS. The whole queue should run in less than a minute. When it's done you should see in the "Host Job Queue", green "Success" buttons stating "Disk Create from StackScript - Setting password for root… done." and "Create Filesystem - 256MB Swap Image". -You may now want to change your Linode VPS's name from the default `linodexxxxxxxx`. Go to the Settings tab, and change the label to be more useful, such as your VPS's short hostname. For instance I have renamed mine to `bitcoin-testnet-pruned` to differentiate it from other VPSs in my account. +You may now want to change your Linode VPS's name from the default `linodexxxxxxxx`. Go to the Settings tab, and change the label to be more useful, such as your VPS's short hostname. For instance you might name it `bitcoin-testnet-pruned` to differentiate it from other VPSs in your account. ## Login to Your VPS @@ -108,7 +103,7 @@ If you watch your Linode control panel, you should see the new computer spin up. First, you'll need the IP address. Click on the "Linodes" tab and you should see a listing of your VPS, the fact that it's running, its "plan", its IP address, and some other information. -Go to your local console and login to the user1 account using that address: +Go to your local console and login to the `standup` account using that address: ``` ssh standup@[IP-ADDRESS] @@ -126,13 +121,13 @@ If you configured your VPS to use an SSH key, the login should be automatic (pos Here's a little catch: _your StackScript is running right now_. The BASH script gets executed the first time the VPS is booted. That means your VPS isn't ready yet. -In past versions, this has taken a bit of time, but the Standup script seems to finish in 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. +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. ## Verify Your Installation -You'll know that stackscrpit is done when the `standup.log` says something like the following: +You'll know that stackscrpit is done when the `tail` of the `standup.log` says something like the following: ``` /root/StackScript - Bitcoin is setup as a service and will automatically start if your VPS reboots and so is Tor /root/StackScript - You can manually stop Bitcoin with: sudo systemctl stop bitcoind.service @@ -141,7 +136,7 @@ You'll know that stackscrpit is done when the `standup.log` says something like At that point, your home directory should look like this: ``` -~$ ls +$ ls bitcoin-0.20.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc SHA256SUMS.asc ``` @@ -165,7 +160,7 @@ 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) " [unknown] /root/StackScript - VERIFICATION SUCCESS / SHA: 35ec10f87b6bc1e44fd9cd1157e5dfa4``` ``` -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 this script.) 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!_ +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!_ ### Read the Logs @@ -175,7 +170,7 @@ It's best to look through the standard StackScript log file, which has all of th `$ sudo more ~root/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. +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: @@ -191,15 +186,15 @@ Although the default Debian 10 image that we are using for your VPS has been mod ### Protected Services -Your Bitcoin VPS installation is minimal and allows almost no communication. This is managed through Part 5 of the StackScript, which sets up Tor and ensures that it's the only way to speak with the Bitcoin ports, other than localhost connections. It's further supplement by the uncomplicated firewall (`ufw`), which blocks everything except SSH connections. +Your Bitcoin VPS installation is minimal and allows almost no communication. This is managed through Part 5 of the StackScript, which sets up Tor and ensures that it's the only way to speak with the Bitcoin ports, other than localhost connections. It's further supplemented by the uncomplicated firewall (`ufw`), which blocks everything except SSH connections. **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 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. It's, as advertised, uncomplicated. 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, uit's ncomplicated. For example adding mail services would just require opening the mail port: `sudo ufw allow 25`. But don't do that. ### Protected Shells -If you provided an IP access for SSH control, SSH (and SCP) access to the server is severely restricted. /etc/hosts.deny disallows anyone from logging in. _We do not suggest changing this_. /etc/hosts.allow then allows specific IP addresses. Just add more IP addresses in a comma-separated list if you need to offer more access. +If you defined "SSH-allowed IPs", SSH (and SCP) access to the server is severely restricted. `/etc/hosts.deny` disallows anyone from logging in. _We do not suggest changing this_. `/etc/hosts.allow` then allows specific IP addresses. Just add more IP addresses in a comma-separated list if you need to offer more access. For example: @@ -221,14 +216,12 @@ echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean false" So now you probably want to play with Bitcoin! -But wait, your Bitcoin daemon is probably still downloading blocks. This alias, from your .bash configuration will tell you how things are going. - -The `bitcoin-cli getblockcount` will tell you how you're currently doing: +But wait, your Bitcoin daemon is probably still downloading blocks. The `bitcoin-cli getblockcount` will tell you how you're currently doing: ``` $ bitcoin-cli getblockcount 1771352 ``` -If it's different every time you type the command, you need to wait before working with Bitcoin. This typically takes 1-6 hours currently fora pruned setup, depending on your precise machine. +If it's different every time you type the command, you need to wait before working with Bitcoin. This takes 1-6 hours currently for a pruned setup, depending on your precise machine. But, once it settles at a number, you're ready to continue! @@ -236,7 +229,7 @@ Still, it might be time for a few more espressos. But soon enough, your system w ## Summary: Setting Up a Bitcoin-Core VPS by Hand -Creating a Bitcoin-Core VPS with a StackScript made the whole process quick, simple and (hopefully) painless. +Creating a Bitcoin-Core VPS with the Standup scripts made the whole process quick, simple and (hopefully) painless. ## What's Next? @@ -249,7 +242,7 @@ You have a few options for what's next: ## Appendix: Bitcoin Installation Types -**Mainnet.** This will download the entirety of the Bitnet blockchain. That's 120G of data (and getting more every day). +**Mainnet.** This will download the entirety of the Bitnet 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. From 2ebd4e0d93b3b36d36b9e9eb5ecf0d8447cf6218 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:30:20 -1000 Subject: [PATCH 035/202] updated for new Bitcoin Standup integration --- 02_3_Setting_Up_Bitcoin_Core_Other.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/02_3_Setting_Up_Bitcoin_Core_Other.md b/02_3_Setting_Up_Bitcoin_Core_Other.md index cbdd6fc..0ddbd73 100644 --- a/02_3_Setting_Up_Bitcoin_Core_Other.md +++ b/02_3_Setting_Up_Bitcoin_Core_Other.md @@ -2,14 +2,12 @@ > :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. -The previous sections presume that you will be [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) or [§2.2: Setting Up a Bitcoin-Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) (as a Linode). However, you can actually create a Bitcoin-Core instance via any methodology of your choice and still follow along with the later steps of this tutorial. +The previous sections presume that you will be creating a full node on a VPS, either by [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) or [§2.2: Setting Up a Bitcoin-Core VPS with Bitcoin Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) (as a Linode). However, you can actually create a Bitcoin-Core instance via any methodology of your choice and still follow along with the later steps of this tutorial. Following are other setup methodologies that we are aware of: -* *[Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup).* A completely mechanical setup from Blockchain Commons that will not only install Bitcoin-Core, but will also install other programs such as Tor. It is available as a [Mac App](https://github.com/BlockchainCommons/Bitcoin-StandUp-MacOS) or as [Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-StandUp-MacOS) (based on our own setup in §2.2, but available for any flavor of Debian). -* *[Setting Up a Bitcoin Node on AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* A step-by-step tutorial by @wolfmcnally on setting on Bitcoin-Core with Amazon Web Services (aws). - -Note that if you use one of these alternative setups, you will need to create the special Bitcoin aliases, as explained in [§3.1: Verifying Your Bitcoin Setup](03_1_Verifying_Your_Bitcoin_Setup.md). +* *[Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup).* The Blockchain Commons methodology used in §2.2 can alternatively be used as a [Mac App](https://github.com/BlockchainCommons/Bitcoin-StandUp-MacOS) or as [Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-StandUp-MacOS) for any Debian setup. +* *[Setting Up a Bitcoin Node on AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* A step-by-step tutorial exists from @wolfmcnally on setting on Bitcoin-Core with Amazon Web Services (AWN). ## What's Next? From 237f25ea98e56d3595c23325cdb7d1e47e4b8b30 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:31:00 -1000 Subject: [PATCH 036/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index c853133..676b004 100644 --- a/TODO.md +++ b/TODO.md @@ -21,7 +21,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 9. Walk through chapters 1-11, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. * Edit Chapter 0 **6/19** * Edit Chapter 1 **6/19** - * Re-edit Chapter 2 + * Re-edit Chapter 2 **6/19** * Check Chapter 3 * Check Chapter 4 * Check Chapter 5 From 90404509b3908f83aed533676fa1dc67b04d0f63 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:40:23 -1000 Subject: [PATCH 037/202] updated chapter 2 links --- 03_0_Understanding_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_0_Understanding_Your_Bitcoin_Setup.md b/03_0_Understanding_Your_Bitcoin_Setup.md index 54a306a..8842858 100644 --- a/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/03_0_Understanding_Your_Bitcoin_Setup.md @@ -2,7 +2,7 @@ You're now ready to begin working with the `bitcoin-cli` command-line interface. But that first requires that you understand your Bitcoin setup and its wallet features, which is what will be explained in this chapter. -For this and future chapters, we presume that you have a VPS with Bitcoin installed, running `bitcoind`. We also presume that you are connected to testnet, allowing for access to bitcoins without using real funds. You can either do this by hand, per [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md) or with a Linode StackScript at Linode.com, per [§2.2: Setting up a Bitcoin-Core VPS with StackScript](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md). +For this and future chapters, we presume that you have a VPS with Bitcoin installed, running `bitcoind`. We also presume that you are connected to testnet, allowing for access to bitcoins without using real funds. You can either do this by hand, per [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md), with Bitcoin Standup at Linode.com, per [§2.2: Setting up a Bitcoin-Core VPS with Bitcoin Standup](02_2_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), or via other means, per [§2.3: Setting up a Bitcoin-Core Machine via Other Means](02_3_Setting_Up_Bitcoin_Core_Other.md). ## Objectives for This Chapter From f6b44515a71cdd36f35fe758c230dea951506c92 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 09:46:23 -1000 Subject: [PATCH 038/202] a few more checks --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 676b004..9b5748e 100644 --- a/TODO.md +++ b/TODO.md @@ -13,8 +13,8 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 4. Ensure Bitcoin Standup covers everything else in previous scripts **6/16** 5. Rewrite the StackScript chapter **6/16** 6. Rewrite the "by-hand" chapter to match Bitcoin Standup (Pending summer work) -7. Reintroduce aliases after setup -8. Figure out what to do about the old `btcblock` on testnet, where there seems to be no CLI way to determine blockheight. +7. Reintroduce aliases after setup **6/19** +8. Figure out what to do about the old `btcblock` on testnet, where there seems to be no CLI way to determine blockheight. **No Known Solution on Testnet** ## 2. Upgrade to 0.20 From abe3e07ea1361d12f9634533024b352da6e8c295 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 10:00:58 -1000 Subject: [PATCH 039/202] updated aliases and how to check if your blockchain is loaded --- 03_1_Verifying_Your_Bitcoin_Setup.md | 46 +++++++++++++--------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/03_1_Verifying_Your_Bitcoin_Setup.md b/03_1_Verifying_Your_Bitcoin_Setup.md index 4b84ee9..f4de325 100644 --- a/03_1_Verifying_Your_Bitcoin_Setup.md +++ b/03_1_Verifying_Your_Bitcoin_Setup.md @@ -4,58 +4,54 @@ Before you start playing with Bitcoin, you should ensure that everything is setup correctly. -## Check Your Aliases +## Create Your Aliases -The Bitcoin setup docs suggest creating a set of aliases. In case you didn't run through those docs, you can create them for your main Bitcoin user with the following command: +We suggest creating some aliases to make it easier to use Bitcoin. +You can do so by putting them in your `.bash_profile`. ``` cat >> ~/.bash_profile < :warning: **WARNING:** The btcblock alias will not work correctly if you try to place it in your .bash_profile by hand, rather than using the "cat" command as suggested. If you want to enter it by hand, you need to adjust the number of backslashes (usually from three each to one each), so make sure you know what you're doing if you aren't entering the commands exactly as suggested. +After you enter these aliases you can either `source .bash_profile` to input them or just log out and back in. 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 aliases directly used here are `btcinfo` and `btcblock`, because they encapsulate much longer and more complex commands. Otherwise, we show the full commands; adjust for your own use as appropriate. - -> :link: **TESTNET vs MAINNET:** Remember that this tutorial generally assumes that you are using testnet. The `btcblock` alias needs to be slightly different on mainnet, where you can use the simpler "wget -O - http://blockchain.info/q/getblockcount 2>/dev/null". +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. ## Run Bitcoind You'll begin your exploration of the Bitcoin network with the `bitcoin-cli` command. However, bitcoind _must_ be running to use bitcoin-cli, as bitcoin-cli sends JSON-RPC commands to the bitcoind. If you used our standard setup, bitcoind should already be up and running. You can double check by looking at the process table. ``` $ ps auxww | grep bitcoind -user1 29360 11.5 39.6 2676812 1601416 ? SLsl Feb23 163:42 /usr/local/bin/bitcoind -daemon +standup 455 1.3 34.4 3387536 1392904 ? SLsl Jun16 59:30 /usr/local/bin/bitcoind -conf=/home/standup/.bitcoin/bitcoin.conf ``` -If it's not running, you'll want to run "/usr/local/bin/bitcoind -daemon" by hand and also place it in your crontab, as explained in [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). +If it's not running, you'll want to run `/usr/local/bin/bitcoind -daemon` by hand and also place it in your crontab, as explained in [§2.1: Setting up a Bitcoin-Core VPS by Hand](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). ## Verify Your Blocks -You should have the whole blockchain downloaded before you start playing. Just run the `btcblock` alias to see if it's all loaded. You'll see two numbers, which tell you how many blocks have loaded out of how many total. +You should have the whole blockchain downloaded before you start playing. Just run the `bitcoin-cli getblockcount` alias to see if it's all loaded. +``` +$ bitcoin-cli getblockcount +1772384 +``` +That tells you what's loaded; you'll then need to check that against an online service that tells you the current block height. -If the two numbers aren't the same, you should wait: -``` -$ btcblock -973212/1090099 -``` -Total download time can take from an hour to several hours, depending on your setup. +> :book: ***What is Block Height?*** Block height is the the distance that a particular block is removed from the genesis block. The current block height is the block height of the newest block added to a blockchain. -If the two numbers are the same, you're fully loaded: -``` -$ btcblock -1090099/1090099 -``` -And that means you're ready to go! +You can do this by looking at a blocknet explorer, such as [the Blockcypher Testnet explorer](https://live.blockcypher.com/btc-testnet/). Does its most recent number match your `getblockcount`? If so, you're up to date. + +> :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`. Unfortunately, functionality like this for testnet has disappeared over the years. + +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. ## Optional: Know Your Server Types -> **TESTNET vs MAINNET:** When you set up your node, you choose to create it as either a Mainnet, Testnet, or Regtest node. Though this document presumes a testnet setup, it's worth understanding how you might access and use the other setup types — even all on the same machine! But, if you're a first time user, skip on past this, as it's not necessary for a basic setup. +> **TESTNET vs MAINNET:** When you set up your node, you choose to create it as either a Mainnet, Testnet, or Regtest node. Though this document presumes a testnet setup, it's worth understanding how you might access and use the other setup types — even all on the same machine! But, if you're a first-time user, skip on past this, as it's not necessary for a basic setup. The type of setup is mainly controlled through the ~/.bitcoin/bitcoin.conf file. If you're running testnet, it probably contains this line: ``` @@ -69,6 +65,7 @@ However, if you want to run several different sorts of nodes simultaneously, you Here's a set of aliases that would make that easier by creating a specific alias for starting and stopping the bitcoind, for going to the bitcoin directory, and for running bitcoin-cli, for each of the mainnet (which has no extra flags), the testnet (which is -testnet), or your regtest (which is -regtest). ``` +cat >> ~/.bash_profile < Date: Fri, 19 Jun 2020 10:21:38 -1000 Subject: [PATCH 040/202] 0.20 updates --- 03_2_Knowing_Your_Bitcoin_Setup.md | 210 +++++++++++++++++------------ 1 file changed, 126 insertions(+), 84 deletions(-) diff --git a/03_2_Knowing_Your_Bitcoin_Setup.md b/03_2_Knowing_Your_Bitcoin_Setup.md index 5a5ffcd..62d48ed 100644 --- a/03_2_Knowing_Your_Bitcoin_Setup.md +++ b/03_2_Knowing_Your_Bitcoin_Setup.md @@ -6,7 +6,7 @@ Before you start playing with Bitcoin, you may always want to come to a better u ## Know Your Bitcoin Directory -To start with, you should understand where everything is kept: the ~/.bitcoin directory. +To start with, you should understand where everything is kept: the `~/.bitcoin` directory. The main directory just contains your config file and the testnet directory: ``` @@ -18,12 +18,12 @@ 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 database debug.log wallet.dat -bitcoind.pid chainstate db.log peers.dat +banlist.dat 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 wallet.dat file, which contains your personal wallet. However, do take careful note of the db.log and debug.log file, which you should refer to if you ever have problems with your setup. +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. -> :link: **TESTNET vs MAINNET:** If you're using mainnet, then _everything_ will instead be placed in the main ~/.bitcoin directory. These various setups _do_ elegantly stack, so if you are using mainnet, testnet, and regtest, you'll find that ~/.bitcoin contains your config file and your mainnet data, ~/.bitcoin/testnet3 contains your testnet data, and ~/.bitcoin/regtest contains your regtest data. +> :link: **TESTNET vs MAINNET:** If you're using mainnet, then _everything_ will instead be placed in the main `~/.bitcoin` directory. These various setups _do_ elegantly stack, so if you are using mainnet, testnet, and regtest, you'll find that `~/.bitcoin` contains your config file and your mainnet data, the `~/.bitcoin/testnet3` directory contains your testnet data, and the `~/.bitcoin/regtest` directory contains your regtest data. ## Know Your Bitcoin-cli Commands @@ -35,70 +35,87 @@ getbestblockhash getblock "blockhash" ( verbosity ) getblockchaininfo getblockcount +getblockfilter "blockhash" ( "filtertype" ) getblockhash height -getblockheader "hash" ( verbose ) +getblockheader "blockhash" ( verbose ) +getblockstats hash_or_height ( stats ) getchaintips -getchaintxstats ( nblocks blockhash ) +getchaintxstats ( nblocks "blockhash" ) getdifficulty -getmempoolancestors txid (verbose) -getmempooldescendants txid (verbose) -getmempoolentry txid +getmempoolancestors "txid" ( verbose ) +getmempooldescendants "txid" ( verbose ) +getmempoolentry "txid" getmempoolinfo getrawmempool ( verbose ) gettxout "txid" n ( include_mempool ) -gettxoutproof ["txid",...] ( blockhash ) +gettxoutproof ["txid",...] ( "blockhash" ) gettxoutsetinfo preciousblock "blockhash" -pruneblockchain +pruneblockchain height +savemempool +scantxoutset "action" ( [scanobjects,...] ) verifychain ( checklevel nblocks ) verifytxoutproof "proof" == Control == -getmemoryinfo ("mode") -getnetworkinginfo +getmemoryinfo ( "mode" ) +getrpcinfo help ( "command" ) +logging ( ["include_category",...] ["exclude_category",...] ) stop uptime == Generating == -generate nblocks ( maxtries ) -generatetoaddress nblocks address (maxtries) +generatetoaddress nblocks "address" ( maxtries ) +generatetodescriptor num_blocks "descriptor" ( maxtries ) == Mining == -getblocktemplate ( TemplateRequest ) +getblocktemplate ( "template_request" ) getmininginfo getnetworkhashps ( nblocks height ) -prioritisetransaction -submitblock "hexdata" ( "dummy" ) +prioritisetransaction "txid" ( dummy ) fee_delta +submitblock "hexdata" ( "dummy" ) +submitheader "hexdata" == Network == -addnode "node" "add|remove|onetry" +addnode "node" "command" clearbanned -disconnectnode "[address]" [nodeid] +disconnectnode ( "address" nodeid ) getaddednodeinfo ( "node" ) getconnectioncount getnettotals getnetworkinfo +getnodeaddresses ( count ) getpeerinfo listbanned ping -setban "subnet" "add|remove" (bantime) (absolute) -setnetworkactive true|false +setban "subnet" "command" ( bantime absolute ) +setnetworkactive state == Rawtransactions == +analyzepsbt "psbt" +combinepsbt ["psbt",...] combinerawtransaction ["hexstring",...] -createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) ( replaceable ) -decoderawtransaction "hexstring" +converttopsbt "hexstring" ( permitsigdata iswitness ) +createpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +createrawtransaction [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +decodepsbt "psbt" +decoderawtransaction "hexstring" ( iswitness ) decodescript "hexstring" -fundrawtransaction "hexstring" ( options ) -getrawtransaction "txid" ( verbose ) -sendrawtransaction "hexstring" ( allowhighfees ) -signrawtransaction "hexstring" ( [{"txid":"id","vout":n,"scriptPubKey":"hex","redeemScript":"hex"},...] ["privatekey1",...] sighashtype ) +finalizepsbt "psbt" ( extract ) +fundrawtransaction "hexstring" ( options iswitness ) +getrawtransaction "txid" ( verbose "blockhash" ) +joinpsbts ["psbt",...] +sendrawtransaction "hexstring" ( maxfeerate ) +signrawtransactionwithkey "hexstring" ["privatekey",...] ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +testmempoolaccept ["rawtx",...] ( maxfeerate ) +utxoupdatepsbt "psbt" ( ["",{"desc":"str","range":n or [n,n]},...] ) == Util == -createmultisig nrequired ["key",...] -estimatefee nblocks -estimatesmartfee conf_target ("estimate_mode") +createmultisig nrequired ["key",...] ( "address_type" ) +deriveaddresses "descriptor" ( range ) +estimatesmartfee conf_target ( "estimate_mode" ) +getdescriptorinfo "descriptor" signmessagewithprivkey "privkey" "message" validateaddress "address" verifymessage "address" "signature" "message" @@ -106,75 +123,85 @@ verifymessage "address" "signature" "message" == Wallet == abandontransaction "txid" abortrescan -addmultisigaddress nrequired ["key",...] ( "account" ) -addwitnessaddress "address" +addmultisigaddress nrequired ["key",...] ( "label" "address_type" ) backupwallet "destination" bumpfee "txid" ( options ) +createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse ) dumpprivkey "address" dumpwallet "filename" encryptwallet "passphrase" -getaccount "address" -getaccountaddress "account" -getaddressesbyaccount "account" -getbalance ( "account" minconf include_watchonly ) -getnewaddress ( "account" ) -getrawchangeaddress -getreceivedbyaccount "account" ( minconf ) +getaddressesbylabel "label" +getaddressinfo "address" +getbalance ( "dummy" minconf include_watchonly avoid_reuse ) +getbalances +getnewaddress ( "label" "address_type" ) +getrawchangeaddress ( "address_type" ) getreceivedbyaddress "address" ( minconf ) -gettransaction "txid" ( include_watchonly ) +getreceivedbylabel "label" ( minconf ) +gettransaction "txid" ( include_watchonly verbose ) getunconfirmedbalance getwalletinfo importaddress "address" ( "label" rescan p2sh ) importmulti "requests" ( "options" ) -importprivkey "privkey" ( "label" ) ( rescan ) -importprunedfunds +importprivkey "privkey" ( "label" rescan ) +importprunedfunds "rawtransaction" "txoutproof" importpubkey "pubkey" ( "label" rescan ) importwallet "filename" keypoolrefill ( newsize ) -listaccounts ( minconf include_watchonly) listaddressgroupings +listlabels ( "purpose" ) listlockunspent -listreceivedbyaccount ( minconf include_empty include_watchonly) -listreceivedbyaddress ( minconf include_empty include_watchonly) +listreceivedbyaddress ( minconf include_empty include_watchonly "address_filter" ) +listreceivedbylabel ( minconf include_empty include_watchonly ) listsinceblock ( "blockhash" target_confirmations include_watchonly include_removed ) -listtransactions ( "account" count skip include_watchonly) -listunspent ( minconf maxconf ["addresses",...] [include_unsafe] [query_options]) +listtransactions ( "label" count skip include_watchonly ) +listunspent ( minconf maxconf ["address",...] include_unsafe query_options ) +listwalletdir listwallets -lockunspent unlock ([{"txid":"txid","vout":n},...]) -move "fromaccount" "toaccount" amount ( minconf "comment" ) +loadwallet "filename" +lockunspent unlock ( [{"txid":"hex","vout":n},...] ) removeprunedfunds "txid" -sendfrom "fromaccount" "toaddress" amount ( minconf "comment" "comment_to" ) -sendmany "fromaccount" {"address":amount,...} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode") -sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount replaceable conf_target "estimate_mode") -setaccount "address" "account" +rescanblockchain ( start_height stop_height ) +sendmany "" {"address":amount} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode" ) +sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount replaceable conf_target "estimate_mode" avoid_reuse ) +sethdseed ( newkeypool "seed" ) +setlabel "address" "label" settxfee amount +setwalletflag "flag" ( value ) signmessage "address" "message" +signrawtransactionwithwallet "hexstring" ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +unloadwallet ( "wallet_name" ) +walletcreatefundedpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime options bip32derivs ) +walletlock +walletpassphrase "passphrase" timeout +walletpassphrasechange "oldpassphrase" "newpassphrase" +walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs ) + +== Zmq == +getzmqnotifications ``` You can also type `bitcoin-cli help [command]` to get even more extensive info on that command. For example: ``` -$ bitcoin-cli help getmininginfo getmininginfo Returns a json object containing mining-related information. Result: -{ - "blocks": nnn, (numeric) The current block - "currentblocksize": nnn, (numeric) The last block size - "currentblockweight": nnn, (numeric) The last block weight - "currentblocktx": nnn, (numeric) The last block transaction - "difficulty": xxx.xxxxx (numeric) The current difficulty - "errors": "..." (string) Current errors - "networkhashps": nnn, (numeric) The network hashes per second - "pooledtx": n (numeric) The size of the mempool - "testnet": true|false (boolean) If using testnet or not - "chain": "xxxx", (string) current network name as defined in BIP70 (main, test, regtest) +{ (json object) + "blocks" : n, (numeric) The current block + "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + "difficulty" : n, (numeric) The current difficulty + "networkhashps" : n, (numeric) The network hashes per second + "pooledtx" : n, (numeric) The size of the mempool + "chain" : "str", (string) current network name (main, test, regtest) + "warnings" : "str" (string) any network and blockchain warnings } Examples: -> bitcoin-cli getmininginfo -> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ ``` -_What is RPC?_ `bitcoin-cli` is just a handy interface that lets you send commands to the `bitcoind`. More specifically, it's an interface that lets you send RPC (or Remote Procedure Protocol) commands to the `bitcoind`. Often, the `bitcoin-cli` command and the RPC command have identical names and interfaces, but some `bitcoin-cli` commands instead provide shortcuts for more complex RPC requests. Generally, the `bitcoin-cli` interface is much cleaner and simpler than trying to send RPC commands by hand, using `curl` or some other method. However, it also has limitations as to what you can ultimately do. +> :book: ***What is RPC?*** `bitcoin-cli` is just a handy interface that lets you send commands to the `bitcoind`. More specifically, it's an interface that lets you send RPC (or Remote Procedure Protocol) commands to the `bitcoind`. Often, the `bitcoin-cli` command and the RPC command have identical names and interfaces, but some `bitcoin-cli` commands instead provide shortcuts for more complex RPC requests. Generally, the `bitcoin-cli` interface is much cleaner and simpler than trying to send RPC commands by hand, using `curl` or some other method. However, it also has limitations as to what you can ultimately do. ## Optional: Know Your Bitcoin Info @@ -190,14 +217,18 @@ For example `bitcoin-cli getnetworkinfo` gives you a variety of information on y ``` $ bitcoin-cli getnetworkinfo { - "version": 150100, - "subversion": "/Satoshi:0.15.1/", + "version": 200000, + "subversion": "/Satoshi:0.20.0/", "protocolversion": 70015, - "localservices": "000000000000000d", - "localrelay": false, + "localservices": "0000000000000408", + "localservicesnames": [ + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, "timeoffset": 0, "networkactive": true, - "connections": 9, + "connections": 10, "networks": [ { "name": "ipv4", @@ -215,28 +246,39 @@ $ bitcoin-cli getnetworkinfo }, { "name": "onion", - "limited": true, - "reachable": false, - "proxy": "", - "proxy_randomize_credentials": false + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true } ], "relayfee": 0.00001000, "incrementalfee": 0.00001000, "localaddresses": [ { - "address": "192.168.1.17", + "address": "45.79.111.171", "port": 18333, - "score": 52 + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fecc:fdb7", + "port": 18333, + "score": 1 + }, + { + "address": "4wrr3ktm6gl4sojx.onion", + "port": 18333, + "score": 4 } ], - "warnings": "Warning: unknown + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} ``` -Feel free to references any of these and to use "bitcoin-cli help" if you want more information on what any of them do. +Feel free to reference any of these and to use "bitcoin-cli help" if you want more information on what any of them do. ## Summary: Knowing Your Bitcoin Setup -The ~/.bitcoin directory contains all of your files, while `bitcoin-cli help` and a variety of info commands can be used to get more information on how your setup and Bitcoin work. +The `~/.bitcoin` directory contains all of your files, while `bitcoin-cli help` and a variety of info commands can be used to get more information on how your setup and Bitcoin work. ## What's Next? From 8c635f30a035351c86080e65cb5bfba15e00595a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 10:24:56 -1000 Subject: [PATCH 041/202] Update TODO.md --- TODO.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/TODO.md b/TODO.md index 9b5748e..910eb83 100644 --- a/TODO.md +++ b/TODO.md @@ -22,19 +22,19 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Edit Chapter 0 **6/19** * Edit Chapter 1 **6/19** * Re-edit Chapter 2 **6/19** - * Check Chapter 3 - * Check Chapter 4 - * Check Chapter 5 - * Check Chapter 6 - * Check Chapter 7 - * Check Chapter 8 - * Check Chapter 9 - * Check Chapter 10 - * Check Chapter 11 + * Edit & Check Chapter 3 + * Edit & Check Chapter 4 + * Edit & Check Chapter 5 + * Edit & Check Chapter 6 ## 3. Add BTCDEB Support 10. Make all examples in [7.4](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_4_Testing_a_Bitcoin_Script.md) and possibly elsewhere use BTCDeb. + * Edit & Integrate Chapter 7 + * Check Chapter 8 + * Check Chapter 9 + * Check Chapter 10 + * Check Chapter 11 Per @ChristopherA: @@ -47,6 +47,7 @@ Per @ChristopherA: Add and document the following new concepts: 11. Add SegWit Transactions. The majority of Bitcoin transactions now use this signing methodology, so it needs to be fully explained and incorporated, alongside its newer bech32 addresses. + * Do we still have to use "bitcoin-cli getnewaddress "" legacy" on CLI? If not, run back through chapters that use legacy in their examples, starting in 3.3 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). 13. Add Wallet Updates. Some improvements have been made to wallet functionality, including Bitcoin Descriptors, and they should be added to the course. 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). From 3861a3443862fd948399a887cfcc27e5ac2bab7d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 10:27:48 -1000 Subject: [PATCH 042/202] Update TODO.md --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 910eb83..8e2e14f 100644 --- a/TODO.md +++ b/TODO.md @@ -47,6 +47,7 @@ Per @ChristopherA: Add and document the following new concepts: 11. Add SegWit Transactions. The majority of Bitcoin transactions now use this signing methodology, so it needs to be fully explained and incorporated, alongside its newer bech32 addresses. + * Add definitions of Segwit and bech32 addresses to 3.3 * Do we still have to use "bitcoin-cli getnewaddress "" legacy" on CLI? If not, run back through chapters that use legacy in their examples, starting in 3.3 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). 13. Add Wallet Updates. Some improvements have been made to wallet functionality, including Bitcoin Descriptors, and they should be added to the course. From fc4f80f9b8d3a260fb53869a73621d852bfa72ec Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 10:41:59 -1000 Subject: [PATCH 043/202] updated for 0.20 --- 03_3_Setting_Up_Your_Wallet.md | 43 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/03_3_Setting_Up_Your_Wallet.md b/03_3_Setting_Up_Your_Wallet.md index a8ca916..8e7166d 100644 --- a/03_3_Setting_Up_Your_Wallet.md +++ b/03_3_Setting_Up_Your_Wallet.md @@ -10,9 +10,9 @@ The first thing you need to do is create an address for receiving payments. This ``` $ bitcoin-cli getnewaddress "" legacy -n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf +moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B ``` -Note that this address begins with an "n" (or sometimes an "m", "2", or "tb1). This signifies that this is a testnet address. +Note that this address begins with an "m" (or sometimes an "n", "2", or "tb1). This signifies that this is a testnet address. The "legacy" flag is necessary to generate a traditional address, rather than a p2sh-segwit or bech32 address. The legacy address is currently required from the command line to make sure that signing works correctly. @@ -20,11 +20,11 @@ The "legacy" flag is necessary to generate a traditional address, rather than a Take careful note of the address. You'll need to give it to whomever will be sending you funds. -_What is a Bitcoin address?_ A Bitcoin address is literally where you receive money. It's like an email address, but for funds. 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 address?*** A Bitcoin address is literally where you receive money. It's like an email address, but for funds. 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. -_What is a P2PKH address?_ A Bitcoin address is also something else: a public key (or more precisely, the 160-bit hash of a public key). For this reason it's called a Pay to PubKey Hash (or P2PKH) address. This public key of your key pair allows you to receive money, while an associated private key lets you spend that money. However, bitcoins may be sent to other sorts of addresses: Pay to Script Hash (P2SH) and Native Segwit (Bech32) addresses feature prominently in the latter part of this tutorial. +> :book: ***What is a P2PKH address?*** A Bitcoin address is also something else: a public key (or more precisely, the 160-bit hash of a public key). For this reason it's called a Pay to PubKey Hash (or P2PKH) address. This public key of your key pair allows you to receive money, while an associated private key lets you spend that money. However, bitcoins may be sent to other sorts of addresses: Pay to Script Hash (P2SH) and Native Segwit (Bech32) addresses feature prominently in the latter part of this tutorial. -_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 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 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! 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 talk about a few other wallet commands that you might want to use in the future. @@ -32,36 +32,45 @@ With a single address in hand, you could jump straight to the next section and b Sometimes you'll need to prove that you control a Bitcoin address (or rather, that you control its private key). This is important because it lets people know that they're sending funds to the right person. This can be done by creating a signature with the `bitcoin-cli signmessage` command, in the form `bitcoin-cli signmessage [address] [message]`. For example: ``` -$ bitcoin-cli signmessage "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf" "Hello, World" -H3yMBZaFeSmG2HgnH38dImzZAwAQADcOiMKTC1fryoV6Y93BelqzDMTCqNcFoik86E8qHa6o3FCmTsxWD7Wa5YY= +$ bitcoin-cli signmessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "Hello, World" +HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI= ``` You'll get the signature as a return. -_What is a signature?_ A digital signature is a combination of a message and a private key that can then be unlocked with a public key. Since there's a one-to-one correspendence between the elements of a keypair, unlocking with a public key proves that the signer controlled the corresponding private key. +> :book: ***What is a signature?*** A digital signature is a combination of a message and a private key that can then be unlocked with a public key. Since there's a one-to-one correspendence between the elements of a keypair, unlocking with a public key proves that the signer controlled the corresponding private key. Another person can then use the `bitcoin-cli verifymessage` command to verify the signature. He inputs the address in question, the signature, and the message: ``` -$ bitcoin-cli verifymessage "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf" "H3yMBZaFeSmG2HgnH38dImzZAwAQADcOiMKTC1fryoV6Y93BelqzDMTCqNcFoik86E8qHa6o3FCmTsxWD7Wa5YY=" "Hello, World" +$ bitcoin-cli verifymessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" true ``` If they all match up, then the other person knows that he can safely transfer funds to the person who signed the message by sending to the address. If some black hat was making up signatures, this would instead produce a negative result: ``` -$ bitcoin-cli verifymessage "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf" "FAKEBZaFeSmG2HgnH38dImzZAwAQADcOiMKTC1fryoV6Y93BelqzDMTCqNcFoik86E8qHa6o3FCmTsxWD7Wa5YY=" "Hello, World" -false +$ bitcoin-cli verifymessage "FAKEV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +error code: -3 +error message: +Invalid address ``` ## Optional: Dump Your Wallet It might seem dangerous having all of your irreplaceable private keys in a single file. That's what `bitcoin-cli backupwallet` is for. It lets you make a copy of your wallet.dat: ``` -$ bitcoin-cli backupwallet backup.dat +$ bitcoin-cli backupwallet ~/backup.dat ``` You can then recover it with `bitcoin-cli importwallet`. ``` $ bitcoin-cli importwallet backup.dat ``` +But note this requires an unpruned node! +``` +$ bitcoin-cli importwallet ~/backup.dat +error code: -4 +error message: +Importing wallets is disabled when blocks are pruned +``` ## Optional: View Your Private Keys @@ -71,15 +80,15 @@ To look at _all_ the keys in your wallet, type `bitcoin-cli dumpwallet ~/mywalle ``` $ bitcoin-cli dumpwallet ~/mywallet.txt { - "filename": "/home/user1/mywallet.txt" + "filename": "/home/standup/mywallet.txt" } ``` -This will create a mywallet.txt file in your home directory with a long list of private keys, addresses, and other information. Mind you, you'd never want to put this data out in a plain text file on a Bitcoin setup with real funds! +This will create a `mywallet.txt` file in your home directory with a long list of private keys, addresses, and other information. Mind you, you'd never want to put this data out in a plain text file on a Bitcoin setup with real funds! More likely, you just want to look at the private key associated with a specific address. This can be done with the `bitcoin-cli dumpprivkey` command. ``` -$ bitcoin-cli dumpprivkey "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf" -cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh +$ bitcoin-cli dumpprivkey "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" +cTv75T4B3NsG92tdSxSfzhuaGrzrmc1rJjLKscoQZXqNRs5tpYhH ``` You can then save that key somewhere safe, preferably somewhere not connected to the internet. @@ -87,7 +96,7 @@ You can import any private key, from a wallet dump or an individual key dump, as ``` $ bitcoin-cli importprivkey cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh ``` -Expect this to take a while, as `bitcoind` needs to reread all past transactions, to see if there are any new ones that it should pay attention to. +Again, expect this to require an unpruned node. Expect this to take a while, as `bitcoind` needs to reread all past transactions, to see if there are any new ones that it should pay attention to. > :information_source: **NOTE:** Many modern wallets prefer [mnemonic codes](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) to generate the seeds necessary to create the private keys. This methodology is not used `bitcoin-cli`, so you won't be able to generate handy word lists to remember your private keys. From 07af202fa4ca3948ab743a486945dc16c5930ead Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 10:48:23 -1000 Subject: [PATCH 044/202] updated with new examples just in case --- 03_3__Interlude_Using_Command-Line_Variables.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/03_3__Interlude_Using_Command-Line_Variables.md b/03_3__Interlude_Using_Command-Line_Variables.md index 18b069a..dad8382 100644 --- a/03_3__Interlude_Using_Command-Line_Variables.md +++ b/03_3__Interlude_Using_Command-Line_Variables.md @@ -20,15 +20,17 @@ These commands clear the NEW_ADDRESS_1 variable, just to be sure, then fill it w You can then use your shell's `echo` command to look at your (new) address: ``` $ echo $NEW_ADDRESS_1 -n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf +mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE ``` Because you have your address in a variable, you can now easily sign a message for that address, without worrying about mistyping the address. You'll of course save that signature into a variable too! ``` $ NEW_SIG_1=$(bitcoin-cli signmessage $NEW_ADDRESS_1 "Hello, World") +$ echo $NEW_SIG_1 +IPYIzgj+Rg4bxDwCyoPiFiNNcxWHYxgVcklhmN8aB2XRRJqV731Xu9XkfZ6oxj+QGCRmTe80X81EpXtmGUpXOM4= ``` The rest of this tutorial will use this style of saving information to variables when it's practical. -_When is it not practical to use command-line variables?_ Command-line variables aren't practical if you need to use the information somewhere other than on the command line. For example, saving your signature may not actually be useful if you're just going to have to send it to someone else in an email. In addition, some future commands will output JSON objects instead of simple information, and variables can't be used to capture that information ... at least not without a _little_ more work. +> :book: ***When is it not practical to use command-line variables?*** Command-line variables aren't practical if you need to use the information somewhere other than on the command line. For example, saving your signature may not actually be useful if you're just going to have to send it to someone else in an email. In addition, some future commands will output JSON objects instead of simple information, and variables can't be used to capture that information ... at least not without a _little_ more work. ## Summary: Using Command-Line Variables From 46c8daeb552952ffc2d366bfd1357cf7e81832f9 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 11:20:47 -1000 Subject: [PATCH 045/202] update to 0.20, including change to "gettransaction" --- 03_4_Receiving_a_Transaction.md | 295 +++++++++++++++++++++----------- 1 file changed, 198 insertions(+), 97 deletions(-) diff --git a/03_4_Receiving_a_Transaction.md b/03_4_Receiving_a_Transaction.md index 2f01b70..bebabb4 100644 --- a/03_4_Receiving_a_Transaction.md +++ b/03_4_Receiving_a_Transaction.md @@ -6,11 +6,11 @@ You're now ready to receive some money at the new address you set up. ## Get Some Money -To do anything more, you need to get some money. On testnet this is done through faucets. Since the money is all pretend, you just go to a faucet, request some money, and it will be sent over to you. We suggest using the faucet at https://testnet.coinfaucet.eu/en/. If it's not available for some reason, search for "bitcoin testnet faucet", and you should find others. +To do anything more, you need to get some money. On testnet this is done through faucets. Since the money is all pretend, you just go to a faucet, request some money, and it will be sent over to you. We suggest using the faucet at https://testnet-faucet.mempool.co/, https://bitcoinfaucet.uo1.net/, or https://testnet.coinfaucet.eu/en/. If they're not available for some reason, search for "bitcoin testnet faucet", and you should find others. To use a faucet, you'll usually need to go to a URL and copy and paste in your address. Note that this is one of those cases where you won't be able to use command-line variables, alas. Afterward, a transaction will be created that sends money from the faucet to you. -_What is a transaction?_ A transaction is a bitcoin exchange. The owner of some bitcoins uses his private key to access those coins, then locks the transaction using the recipient's public key. +> :book: ***What is a transaction?*** A transaction is a bitcoin exchange. The owner of some bitcoins uses his private key to access those coins, then locks the transaction using the recipient's public key. > :link: **TESTNET vs MAINNET:** Sadly, there are no faucets in real life. If you were playing on the mainnet, you'd need to go and actually buy bitcoins at a bitcoin exchange or ATM, or you'd need to get someone to send them to you. Testnet life is much easier. @@ -25,28 +25,28 @@ But wait, there's no balance yet!? Welcome to the world of Bitcoin latency.The problem is that your transaction hasn't yet been recorded in a block! -_What is a block?_ Transactions are transmitted across the network and gathered into blocks by miners. These blocks are secured with a mathematical proof-of-work, which proves that computing power has been expended as part of the block creation. It's that proof-of-work (multiplied over many blocks, each built atop the last) that ultimately keeps Bitcoin secure. +> :book: ***What is a block?*** Transactions are transmitted across the network and gathered into blocks by miners. These blocks are secured with a mathematical proof-of-work, which proves that computing power has been expended as part of the block creation. It's that proof-of-work (multiplied over many blocks, each built atop the last) that ultimately keeps Bitcoin secure. -_What is a miner?_ A miner is a participant of the Bitcoin network who works to create blocks. It's a paying job: when a miner successfully creates a block, he is paid a one-time reward plus the fees for the transactions in his block. Mining is big business. Miners tend to run on special hardware, accelerated in ways that make it more likely that they'll be able to create blocks. They also tend to be part of mining pools, where the miners all agree to share out the rewards when one of them successfully creates a block. +> :book: ***What is a miner?*** A miner is a participant of the Bitcoin network who works to create blocks. It's a paying job: when a miner successfully creates a block, he is paid a one-time reward plus the fees for the transactions in his block. Mining is big business. Miners tend to run on special hardware, accelerated in ways that make it more likely that they'll be able to create blocks. They also tend to be part of mining pools, where the miners all agree to share out the rewards when one of them successfully creates a block. Fortunately, `bitcoin-cli getunconfirmedbalance` should still show your updated balance as long as the initial transaction has been created: ``` $ bitcoin-cli getunconfirmedbalance -0.47000000 +0.01010000 ``` If that's still showing a zero too, you're probably moving through this tutorial too fast. Wait a second. The coins should show up unconfirmed, then rapidly move to confirmed. Do note that a coin can move from unconfirmedbalance to confirmedbalance almost immediately, so make sure you check both. However, if your `getbalance` and your `getunconfirmedbalance` both still show zero in ten minutes, then there's probably something wrong with the faucet, and you'll need to pick another. ### Gain Confidence in Your Money -You can use `bitcoin-cli getbalance "*" [n]` to see if a confirmed balance is 'n' blocks deep. +You can use `bitcoin-cli getbalance "*" [n]`, where you replace `[n]` with an integer, to see if a confirmed balance is 'n' blocks deep. -_What is block depth?_ After a block is built and confirmed, another block is built on top of it, and another ... Because this is a stochastic process, there's some chance for reversal when a block is still new. Thus, a block has to be buried several blocks deep in a chain before you can feel totally confident in your funds. Each of those blocks tends to be built in an average of 10 minutes ... so it usually takes about an hour for a confirmed transaction to receive full confidence. +> :book: ***What is block depth?*** After a block is built and confirmed, another block is built on top of it, and another ... Because this is a stochastic process, there's some chance for reversal when a block is still new. Thus, a block has to be buried several blocks deep in a chain before you can feel totally confident in your funds. Each of those blocks tends to be built in an average of 10 minutes ... so it usually takes about an hour for a confirmed transaction to receive six blooks deep, which is the measure for full confidence in Bitcoin. -The following shows that our transaction has been confirmed one time, but not twice: +The following shows that our transactions have been confirmed one time, but not twice: ``` -$ bitcoin-cli getbalance "*" 1 -0.47000000 -$ bitcoin-cli getbalance "*" 2 +$ bitcoin-cli getbalance "*" 1 +0.01010000 +$ bitcoin-cli getbalance "*" 2 0.00000000 ``` Obviously, every ten minutes or so this depth will increase. @@ -59,15 +59,20 @@ The `bitcoin-cli getwalletinfo` command gives you more information on the balanc ``` $ bitcoin-cli getwalletinfo { - "walletversion": 130000, - "balance": 0.47000000, + "walletname": "", + "walletversion": 169900, + "balance": 0.01010000, "unconfirmed_balance": 0.00000000, "immature_balance": 0.00000000, - "txcount": 1, - "keypoololdest": 1488216266, - "keypoolsize": 100, + "txcount": 2, + "keypoololdest": 1592335137, + "keypoolsize": 999, + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "keypoolsize_hd_internal": 1000, "paytxfee": 0.00000000, - "hdmasterkeyid": "b91d5ec57d5ae3e90fff50d12e819429b6496b94" + "private_keys_enabled": true, + "avoid_reuse": false, + "scanning": false } ``` @@ -78,115 +83,211 @@ Your money came into your wallet via a transaction. You can discover that transa $ bitcoin-cli listtransactions [ { - "account": "", - "address": "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf", + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", "category": "receive", - "amount": 0.47000000, + "amount": 0.01000000, "label": "", - "vout": 0, - "confirmations": 2, - "blockhash": "00000000fa4fdd22a2c33c6200b68239939ad65af3f1a48ecea25f8200f5d66b", - "blockindex": 45, - "blocktime": 1488307692, - "txid": "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2", + "vout": 1, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", "walletconflicts": [ ], - "time": 1488307692, - "timereceived": 1488307696, + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no" + }, + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.00010000, + "label": "", + "vout": 0, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 72, + "blocktime": 1592600085, + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "walletconflicts": [ + ], + "time": 1592599938, + "timereceived": 1592599938, "bip125-replaceable": "no" } ] + ``` -This shows one transaction ("88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2") that was received ("receive") by a specific address in my wallet ("n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf") for a specific amount ("0.47000000"). +This shows two transactions (`8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9`) and (`ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36`) for a specific amount (`0.01000000` and `0.00010000`), which were both received (`receive`) by the same address in our wallet (`mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE`). That's bad key hygeine, by the by: you should use a new address for every single Bitcoin you ever receive. In this case, we got impatient because the first faucet didn't seem to be working. You can access similar information with the `bitcoin-cli listunspent` command, but it only shows the transactions for the money that you haven't spent. These are called UTXOs, and will be vitally important when you're sending money back out into the Bitcoin world: ``` $ bitcoin-cli listunspent [ { - "txid": "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2", + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", "vout": 0, - "address": "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf", - "account": "", - "scriptPubKey": "76a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac", - "amount": 0.47000000, - "confirmations": 3, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 1, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "vout": 1, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.01000000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true } ] ``` Note that bitcoins are not just a homogeneous mess of cash jammed into your pocket. Each individual transaction that you receive or that you send is placed into the immutable blockchain ledger, in a block. You can see these individual transactions when you look at your unspent money. This means that bitcoin spending isn't quite as anonymous as you'd think. Though the addresses are fairly private, transactions can be examined as they go in and out of addresses. This makes privacy vulnerable to statistical analysis. It also introduces some potential non-fungibility to bitcoins, as you can track back through series of transactions, even if you can't track a specific "bitcoin". -_Why are all of these bitcoin amounts in fractions?_ Bitcoins are produced slowly, and so there are relatively few in circulation. As a result, each bitcoin over on the mainnet is worth quite a bit (~ $1,000 at the time of this writing). This means that people usually work in fractions. In fact, .47 BTC would be quite a lot in the real-world. You'll often be dealing with even smaller fractions on mainnet. For this reason, names have appeared for smaller amounts of bitcoins, including millibitcoins or mBTCs (one-thousandth of a bitcoin), microbitcoins or bits or μBTCs (one-millionth of a bitcoin), and satoshis (one hundred millionth of a bitcoin). +> :book: ***Why are all of these bitcoin amounts in fractions?*** Bitcoins are produced slowly, and so there are relatively few in circulation. As a result, each bitcoin over on the mainnet is worth quite a bit (~ $9,000 at the time of this writing). This means that people usually work in fractions. In fact, the .0101 in Testnet coins would be worth about $100 if they were on the mainnet. For this reason, names have appeared for smaller amounts of bitcoins, including millibitcoins or mBTCs (one-thousandth of a bitcoin), microbitcoins or bits or μBTCs (one-millionth of a bitcoin), and satoshis (one hundred millionth of a bitcoin). ## Examine Your Transaction -You can get more information on a transaction with the `bitcoin-cli getrawtransaction` command: +You can get more information on a transaction with the `bitcoin-cli gettransaction` command: ``` -$ bitcoin-cli getrawtransaction "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2" -010000000133261a25b44689bab2c6a207381ca21d243de9bbf21f0fa40c3a26ba7282a87b000000006b483045022100a2640761810dfc34dabed599928243afe24e13f520f780ceb382843a530a577c022050b92f5d9843d70ddb60a0aa294938862f2b7372818d6149ffd4f6adec5cf6c80121034dcaa515c2fda0f4a50b90a6d798e01c00a870bef0bd97154066fe202d2b5d75feffffff02c029cd02000000001976a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac17791703000000001976a914e176ee39c642344df2180863e27e2e936307273c88ac07a41000 -``` -Granted, this isn't super useful, because it's the hex-encoded transaction data. Fortunately, you can get a more verbose description just by adding a '1' to your command: -#This didn work for me. I ended by using the command gettransaction instead getrawtransaction. -`` -$ bitcoin-cli getrawtransaction "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2" 1 +$ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9" { - "hex": "010000000133261a25b44689bab2c6a207381ca21d243de9bbf21f0fa40c3a26ba7282a87b000000006b483045022100a2640761810dfc34dabed599928243afe24e13f520f780ceb382843a530a577c022050b92f5d9843d70ddb60a0aa294938862f2b7372818d6149ffd4f6adec5cf6c80121034dcaa515c2fda0f4a50b90a6d798e01c00a870bef0bd97154066fe202d2b5d75feffffff02c029cd02000000001976a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac17791703000000001976a914e176ee39c642344df2180863e27e2e936307273c88ac07a41000", - "txid": "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2", - "hash": "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2", - "size": 226, - "vsize": 226, - "version": 1, - "locktime": 1090567, - "vin": [ + "amount": 0.01000000, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no", + "details": [ { - "txid": "7ba88272ba263a0ca40f1ff2bbe93d241da21c3807a2c6b2ba8946b4251a2633", - "vout": 0, - "scriptSig": { - "asm": "3045022100a2640761810dfc34dabed599928243afe24e13f520f780ceb382843a530a577c022050b92f5d9843d70ddb60a0aa294938862f2b7372818d6149ffd4f6adec5cf6c8[ALL] 034dcaa515c2fda0f4a50b90a6d798e01c00a870bef0bd97154066fe202d2b5d75", - "hex": "483045022100a2640761810dfc34dabed599928243afe24e13f520f780ceb382843a530a577c022050b92f5d9843d70ddb60a0aa294938862f2b7372818d6149ffd4f6adec5cf6c80121034dcaa515c2fda0f4a50b90a6d798e01c00a870bef0bd97154066fe202d2b5d75" - }, - "sequence": 4294967294 + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1 } ], - "vout": [ - { - "value": 0.47000000, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 fd67e8a7c7813e7a5c376eb71074f373d924d968 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf" - ] - } - }, - { - "value": 0.51869975, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 e176ee39c642344df2180863e27e2e936307273c OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914e176ee39c642344df2180863e27e2e936307273c88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "n256of3JH1A6X8AQUU7LYkcaRcmrfGjGKC" - ] - } - } - ], - "blockhash": "00000000fa4fdd22a2c33c6200b68239939ad65af3f1a48ecea25f8200f5d66b", - "confirmations": 3, - "time": 1488307692, - "blocktime": 1488307692 + "hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00" } ``` -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 .47 BTC in the transaction, another .51869975 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. +The `gettransaction` command will detail transanctions that are in your wallet, such as this one, that was sent to us. -> :warning: **WARNING:** These commands will not work in some situations. To be able to view a raw transaction on a standard node, some of the money must be unspent, or the transaction must still be in your mempool — which means that this command will work fine for the money you've just received, but not for old stuff. If you want to be able to view older transactions that have been spent, you can do so by maintaining a set of all transactions with the txindex=1 configuration, which is what our scripts suggest for all non-pruned instances. (You can't maintain a transaction index if your node is pruned.) +Note that `gettransaction` has two optional arguments: +``` +$ bitcoin-cli help gettransaction +gettransaction "txid" ( include_watchonly verbose ) + +Get detailed information about in-wallet transaction + +Arguments: +1. txid (string, required) The transaction id +2. include_watchonly (boolean, optional, default=true for watch-only wallets, otherwise false) Whether to include watch-only addresses in balance calculation and details[] +3. verbose (boolean, optional, default=false) Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction) +``` +By setting these two true or false, we can choose to include watch-only addresses in the output (which we don't care about) or look at more verbose output (which we do). + +Here's what this data instead looks at when we set `include_watchonly` to `false` and `verbose` to `true`. +``` +$ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9" false true +{ + "amount": 0.01000000, + "confirmations": 3, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no", + "details": [ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1 + } + ], + "hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00", + "decoded": { + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "hash": "d4ae2b009c43bfe9eba96dcd16e136ceba2842df3d76a67d689fae5975ce49cb", + "version": 2, + "size": 249, + "vsize": 168, + "weight": 669, + "locktime": 1772327, + "vin": [ + { + "txid": "80f57b9779a769eb8772faf319265a46b94499d7d51df5db7a13b0d17749d014", + "vout": 1, + "scriptSig": { + "asm": "0014e85ba02862dbadabd6d204fcc8bb5d54658c7d4f", + "hex": "160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4f" + }, + "txinwitness": [ + "304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e13301", + "022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01010143, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 5c3bfb36b03f279967977ca9d1e35185e3991778 OP_EQUAL", + "hex": "a9145c3bfb36b03f279967977ca9d1e35185e399177887", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N1ev1WKevSsdmAvRqZf7JjvDg223tPrVCm" + ] + } + }, + { + "value": 0.01000000, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1b72503639a13f190bf79acf6d76255d772360b7 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE" + ] + } + } + ] + } +} +``` +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 ... ## Optional: Use a Block Explorer @@ -196,17 +297,17 @@ Currently, our preferred block explorer is [https://live.blockcypher.com/](https You can use it to look up transactions for an address: -[https://live.blockcypher.com/btc-testnet/address/n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf/](https://live.blockcypher.com/btc-testnet/address/n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf/) +[https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/](https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/) You can also use it to look at individual transactions: -[https://live.blockcypher.com/btc-testnet/tx/88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2/](https://live.blockcypher.com/btc-testnet/tx/88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2/) +[https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/](https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/) A block explorer doesn't generally provide any more information than a command line look at a raw transaction; it just does a good job of highlighting the important information and putting together the puzzle pieces, including the transaction fees behind a transaction — another concept that we'll be covering in future sections. ## Summary: Receiving a Transaction -Faucets will give you money on the testnet. They come in as raw transactions, which can be examined with `getrawtransaction` or a block explorer. Once you've receive a transaction, you can see it in your balance and your wallet. +Faucets will give you money on the testnet. They come in as raw transactions, which can be examined with `gettransaction` or a block explorer. Once you've receive a transaction, you can see it in your balance and your wallet. ## What's Next? From dfafd03583c37e6dc744069e0bfb24fea09d8c4d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 11:23:28 -1000 Subject: [PATCH 046/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 8e2e14f..2c71e18 100644 --- a/TODO.md +++ b/TODO.md @@ -22,7 +22,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Edit Chapter 0 **6/19** * Edit Chapter 1 **6/19** * Re-edit Chapter 2 **6/19** - * Edit & Check Chapter 3 + * Edit & Check Chapter 3 **6/19** * Edit & Check Chapter 4 * Edit & Check Chapter 5 * Edit & Check Chapter 6 From debedeffcc6fedb0700d48f41f9ce6e540bdfac4 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 12:06:56 -1000 Subject: [PATCH 047/202] updating all command responses and checking for 0.20 --- 04_1_Sending_Coins_The_Easy_Way.md | 49 +++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/04_1_Sending_Coins_The_Easy_Way.md b/04_1_Sending_Coins_The_Easy_Way.md index ab72edc..d2666ca 100644 --- a/04_1_Sending_Coins_The_Easy_Way.md +++ b/04_1_Sending_Coins_The_Easy_Way.md @@ -8,11 +8,11 @@ The `bitcoin-cli` offers three major ways to send coins: as a simple command; as Before you send any money on the Bitcoin network, you should think about what transaction fees you're going to pay. -_What is a transaction fee?_ There's no such thing as a free lunch. Miners incorporate transactions into blocks because they're paid to do so. Not only do they get paid by the network for making the block, but they also get paid by transactors for including their transactions. If you don't pay a fee, your transaction might get stuck ... forever (or, until saved by some of the tricks in section five). +> :book: ***What is a transaction fee?*** There's no such thing as a free lunch. Miners incorporate transactions into blocks because they're paid to do so. Not only do they get paid by the network for making the block, but they also get paid by transactors for including their transactions. If you don't pay a fee, your transaction might get stuck ... forever (or, until saved by some of the tricks in [Chapter Five](05_0_Controlling_Bitcoin_Transactions.md)). When you're using the simple and automated methods for creating transactions, as outlined here and in [§4.5: Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), Bitcoin will calculate transaction fees for you. This is done using Floating Fees, where the `bitcoind` watches how long transactions are taking to confirm and automatically calculates for you what to spend. -You can help control this by putting rational values into your ~/.bitcoin/bitcoin.conf. The following low-cost values would ensure that there was a minimum transaction fee of 10,000 satoshis per kByte of data in your transaction and request that the floating fees figure out a good amount to get your transaction somewhere into the next six blocks. +You can help control this by putting rational values into your `~/.bitcoin/bitcoin.conf`. The following low-cost values would ensure that there was a minimum transaction fee of 10,000 satoshis per kByte of data in your transaction and request that the floating fees figure out a good amount to get your transaction somewhere into the next six blocks. ``` mintxfee=0.0001 txconfirmtarget=6 @@ -22,15 +22,24 @@ However, under the theory that you don't want to wait around while working on a mintxfee=0.001 txconfirmtarget=1 ``` -In order to get through this tutorial, we're willing to spend 100,00 satoshis per kB on every transaction (about $1!) 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 a a quarter than a buck.) +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.) 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 & +``` ## Get an Address -You need somewhere to send your coins to. Usually, someone would send you an address, and perhaps give you a signature to prove they own that address. Alternatively, they might give you a QR code to scan, so that you can't make mistakes when typing in the address. In our case, we're going to send coins to `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, which is a return address for TP's TestNet faucet. +You need somewhere to send your coins to. Usually, someone would send you an address, and perhaps give you a signature to prove they own that address. Alternatively, they might give you a QR code to scan, so that you can't make mistakes when typing in the address. In our case, we're going to send coins to `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, which is a return address for an old Tesetnet faucet. -_What is a QR code?_ A QR code is just an encoding of a Bitcoin address. Many wallets will generate QR codes for you, while some sites will convert from an address to a QR code. Obviously, you should only accept a QR code from a site that you absolutely trust. A payer can use a bar-code scanner to read in the QR code, then pay to it. +> :book: ***What is a QR code?*** A QR code is just an encoding of a Bitcoin address. Many wallets will generate QR codes for you, while some sites will convert from an address to a QR code. Obviously, you should only accept a QR code from a site that you absolutely trust. A payer can use a bar-code scanner to read in the QR code, then pay to it. ## Send the Coins @@ -38,7 +47,7 @@ You're now ready to send some coins. This is actually quite simple via the comma ``` $ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.1) $ echo $txid -586b3ff591d43948ed4107216be52d831c551747b469626a6b7c84bbf1639f76 +93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8 ``` 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. @@ -50,35 +59,33 @@ You'll receive a txid back when you issue this command. You can look at your transaction using your transaction id: ``` -$ bitcoin-cli gettransaction $txid { - "amount": -0.10000000, - "fee": -0.00022600, + "amount": -0.00100000, + "fee": -0.00022200, "confirmations": 0, - "trusted": false, - "txid": "586b3ff591d43948ed4107216be52d831c551747b469626a6b7c84bbf1639f76", + "trusted": true, + "txid": "93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8", "walletconflicts": [ ], - "time": 1490742233, - "timereceived": 1490742233, - "bip125-replaceable": "unknown", + "time": 1592604194, + "timereceived": 1592604194, + "bip125-replaceable": "no", "details": [ { - "account": "", "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", "category": "send", - "amount": -0.10000000, - "vout": 0, - "fee": -0.00022600, + "amount": -0.00100000, + "vout": 1, + "fee": -0.00022200, "abandoned": false } ], - "hex": "0200000001a8b61dba544525ad267644cb78f07c1ba58586ff9089aec3ac24d8764dc21dfb000000006a47304402204c38c2530d3283200e4fd3b2d22e609fc6dc941fd3ac4bc8b73ad5a86607e723022050056ae6cfc3233fb38459a6fd5e63d54e4c85e17b91d66fb915e3977a1c77dd0121027a313901f2ac34c87761513cabe69ca9ca61e2db3c7e6f89d7eccd7fc0a5917cfeffffff0280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac4082820b000000001976a914a091d978794d50e5caa3e5454cc8633240640d6688aca6de1000" + "hex": "0200000001e982921bb0189afc486e20bb05cc5825c71a0ba8868043ed04ece9ab0cb12a8e010000006a47304402200fc493a01c5c9d9574f7c321cee6880f7f1df847be71039e2d996f7f75c17b3d02203057f5baa48745ba7ab5f1d4eed11585bd8beab838b1ca03a4138516fe52b3b8012102fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9bafeffffff02e8640d0000000000160014d37b6ae4a917bcc873f6395741155f565e2dc7c4a0860100000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac780b1b00" } ``` -You can see not only the amount transferred (.1 BTC) but also a transaction fee (.000226 BTC), which is about a quarter of the .001 BTC/kB minimum fee that was set, which suggests that the transaction was about a quarter of a kB in size. +You can see not only the amount transferred (.001 BTC) but also a transaction fee (.000222 BTC), which is about a quarter of the .001 BTC/kB minimum fee that was set, which suggests that the transaction was about a quarter of a kB in size. -While you are waiting for this transaction to clear, you'll note that `bitcoin-cli getbalance` shows that all of your money is gone (or, at least, all of your money from a single incoming transaction). Similarly, `bitcoin-cli listunspent` would show an appropriately sized blob of incoming money was gone. There's a reason for this: whenever you get money in, you have to send it _all_ out together, and you have to perform some gymnastics if you actually want to keep some of it! Once again, `sendtoaddress` takes care of this all for you, which means you don't have to worry about it in full until you use a raw transaction to send out money. +While you are waiting for this transaction to clear, you'll note that `bitcoin-cli getbalance` shows that all of your money is gone (or, at least, all of your money from a single incoming transaction). Similarly, `bitcoin-cli listunspent` will show that an entire transaction is gone, even if it was more than what you wanted to send. There's a reason for this: whenever you get money in, you have to send it _all_ out together, and you have to perform some gymnastics if you actually want to keep some of it! Once again, `sendtoaddress` takes care of this all for you, which means you don't have to worry about making change until you send a raw transaction. ## Summary: Sending Coins the Easy Way From fadd64d66ca47fd05282f4ee1868d7f3d9a16c5f Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 12:08:43 -1000 Subject: [PATCH 048/202] clarification --- 04_1_Sending_Coins_The_Easy_Way.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_1_Sending_Coins_The_Easy_Way.md b/04_1_Sending_Coins_The_Easy_Way.md index d2666ca..447a98c 100644 --- a/04_1_Sending_Coins_The_Easy_Way.md +++ b/04_1_Sending_Coins_The_Easy_Way.md @@ -85,7 +85,7 @@ You can look at your transaction using your transaction id: ``` You can see not only the amount transferred (.001 BTC) but also a transaction fee (.000222 BTC), which is about a quarter of the .001 BTC/kB minimum fee that was set, which suggests that the transaction was about a quarter of a kB in size. -While you are waiting for this transaction to clear, you'll note that `bitcoin-cli getbalance` shows that all of your money is gone (or, at least, all of your money from a single incoming transaction). Similarly, `bitcoin-cli listunspent` will show that an entire transaction is gone, even if it was more than what you wanted to send. There's a reason for this: whenever you get money in, you have to send it _all_ out together, and you have to perform some gymnastics if you actually want to keep some of it! Once again, `sendtoaddress` takes care of this all for you, which means you don't have to worry about making change until you send a raw transaction. +While you are waiting for this transaction to clear, you'll note that `bitcoin-cli getbalance` shows that all of your money is gone (or, at least, all of your money from a single incoming transaction). Similarly, `bitcoin-cli listunspent` will show that an entire transaction is gone, even if it was more than what you wanted to send. There's a reason for this: whenever you get money in, you have to send it _all_ out together, and you have to perform some gymnastics if you actually want to keep some of it! Once again, `sendtoaddress` takes care of this all for you, which means you don't have to worry about making change until you send a raw transaction. In this case, a new transaction will appear with your change when your spend is incorporated into a block. ## Summary: Sending Coins the Easy Way From f258edbe72bc8f6f9cfc238eb397563c8057a8c8 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 13:18:17 -1000 Subject: [PATCH 049/202] update for 0.20 --- 04_2_Creating_a_Raw_Transaction.md | 183 +++++++++++++++-------------- 1 file changed, 97 insertions(+), 86 deletions(-) diff --git a/04_2_Creating_a_Raw_Transaction.md b/04_2_Creating_a_Raw_Transaction.md index be02788..8cd2b2e 100644 --- a/04_2_Creating_a_Raw_Transaction.md +++ b/04_2_Creating_a_Raw_Transaction.md @@ -8,7 +8,7 @@ You're now ready to create Bitcoin raw transactions. This allows you to send mon Before you dive into actually creating raw transactions, you should make sure you understand how a Bitcoin transaction works. It's all about the UTXOs. -_What is a UTXO?_ When you receive cash in your Bitcoin wallet, it appears as an individual transaction. Each of these transactions is called a Unspent Transaction Output (UTXO). It doesn't matter if various payments were made to the same address or to multiple addresses: each incoming transaction remains distinct in your wallet as a UTXO. +> :book: ***What is a UTXO?*** When you receive cash in your Bitcoin wallet, it appears as an individual transaction. Each of these transactions is called a Unspent Transaction Output (UTXO). It doesn't matter if various payments were made to the same address or to multiple addresses: each incoming transaction remains distinct in your wallet as a UTXO. When you create a new outgoing transaction, you gather together one or more UTXOs, each of which represents a blob of money that you received. You use these as inputs for a new transaction. Together their amount must equal what you want to spend _or more_. Then, you generate one or more outputs, which give the money represented by the inputs to one or more people. This creates new UTXOs for the recipients, which may then use _those_ to fund future transactions. @@ -21,43 +21,50 @@ In order to create a new raw transaction, you must know what UTXOs you have on-h $ bitcoin-cli listunspent [ { - "txid": "ee9805676271f6244eba94c3d1a48b303a8f8359bf711c630eb6f2ea339d0e72", + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", "vout": 0, - "address": "mrS1ypy2pCweh2nBpkMD7r2T3Zj344wxaY", - "account": "", - "scriptPubKey": "76a91477ba616a2778b05a5fd73c7449964050fd1a6fd288ac", - "amount": 0.08000000, - "confirmations": 2, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 20, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true }, { - "txid": "c1abb6951e6a9aae7e384412b69b69e59c10daac9397d01d0c52b7bc6278d589", + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", "vout": 1, - "address": "mygxipnJUsBgFvscKAaoxDdE8aCmHhRfTZ", - "account": "", - "scriptPubKey": "76a914c756c7bd67bf83d83c04e3dc6fd1ff0c6fe8ea9888ac", - "amount": 0.07800000, - "confirmations": 1, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00050000, + "confirmations": 3, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true }, { - "txid": "ab7ca727055b812df882298f4e6e10ec699fb6250d843c813623171781f896d8", + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", "vout": 0, - "address": "mygxipnJUsBgFvscKAaoxDdE8aCmHhRfTZ", - "account": "", - "scriptPubKey": "76a914c756c7bd67bf83d83c04e3dc6fd1ff0c6fe8ea9888ac", - "amount": 0.07800000, - "confirmations": 1, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 3, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true } ] -``` -This listing shows three different UTXOs, worth .08, .078, and .078 BTC. Note that each has its own distinct txid and remains distinct in the wallet, even though two of them were sent to the same address. (Bad practice! But used as an example here to show that transaction stay distinct, no matter what!) -When you want to spend a UTXO, it's not sufficient to just know the transaction id. That's because each transaction can have multiple outputs! Remember that first chunk of money that the faucet sent us? In the transaction, some money went to us and some went to someone else. The `txid` refers to the overall transaction, while a `vout` says which of multiple outputs you've received. In this list, two of our UTXOs are the 0th vout of a transaction, and the other is the 1st. This makes a difference! +``` +This listing shows three different UTXOs, worth .0001, .0005 and .00022 BTC. Note that each has its own distinct txid and remains distinct in the wallet, even the last two, which were sent to the same address. + +When you want to spend a UTXO, it's not sufficient to just know the transaction id. That's because each transaction can have multiple outputs! Remember that first chunk of money that the faucet sent us? In the transaction, some money went to us and some went to someone else. The `txid` refers to the overall transaction, while a `vout` says which of multiple outputs you've received. In this list, each of these transactions is the 0th `vout` of a previous transaction, but _that doesn't have to be the case_. So, txid+vout=UTXO. This will be the foundation of any raw transaction. @@ -65,20 +72,18 @@ 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. +> :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.) ### Prepare the Raw Transaction For best practices, we'll start out each transaction by carefully recording the txids and vouts that we'll be spending. -In this case, we're going to spend the oldest transaction, worth .08 BTC, because that's the one that's been validated the most: +In this case, we're going to spend the one worth .00050000 BTC because it's the only one with a decent value. ``` -$ utxo_txid="ee9805676271f6244eba94c3d1a48b303a8f8359bf711c630eb6f2ea339d0e72" -$ utxo_vout="0" +$ utxo_txid="61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a" +$ utxo_vout="1" ``` -> :link: **TESTNET vs MAINNET:** Obviously the "validated-the-most" criteria would matter a lot more on mainnet, where real money is being used. - You should similarly record your recipient address, to make sure you have it right. We're again sending some money back to the TP faucet: ``` $ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" @@ -86,13 +91,27 @@ $ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" As always, check your variables carefully, to make sure they're what you expect! ``` $ echo $utxo_txid -ee9805676271f6244eba94c3d1a48b303a8f8359bf711c630eb6f2ea339d0e72 +61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a $ echo $utxo_vout -0 +1 $ echo $recipient n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi ``` -That recipient is particularly important, because if you mess it up, your money is _gone_! So triple check it. +That recipient is particularly important, because if you mess it up, your money is _gone_! (And as we already saw, choosing the wrong transaction can result in lost money!) So triple check it all. + +### Understand the Transaction Fee + +Each transaction has a fee associated with. It's _implicit_ when you send a raw transaction: the amount that you will pay as a fee is always equal to the amount of your input minus the amount of your output. So, you have to decrease your output a little bit from your input to make sure that your transaction goes out. + +> :warning: **WARNING:** This is the very dangerous part of raw transactions!! Because you automatically expend all of the amount in the UTXOs that you use, it's critically important to make sure that you know: (1) precisely what UTXOs you're using; (2) exactly how much money they contain; (3) exactly how much money you're sending out; and (4) what the difference is. If you mess up and you use the wrong UTXO (with more money than you thought) or if you send out too little money, the excess is lost. Forever. Don't make that mistake! Know your inputs and outputs _precisely_. Or better, don't use raw transactions except as part of a carefully considered and triple-checked program. + +> :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. + +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. ### Write the Raw Transaction @@ -111,43 +130,32 @@ $ bitcoin-cli createrawtransaction "'$your_recipient'": bitcoin_amount }''' ``` - Yeah, there are all kinds of crazy quotes there, but trust that they'll do the right thing. Use `'''` to mark the start and end of the JSON array and the JSON object. Protect normal words like `"this"` and normal numbers like `0`. If they're variables, insert single quotes, like `"'$this_word'"` and `'$this_num'`. (Whew. You'll get used to it.) + Yeah, there are all kinds of crazy quotes there, but trust that they'll do the right thing. Use `'''` to mark the start and end of the JSON array and the JSON object. Protect normal words like `"this"`, but you don't need to protect normal numbers: `0`. If they're variables, insert single quotes, like `"'$this_word'"` and `'$this_num'`. (Whew. You'll get used to it.) Here's a command that creates a raw transaction to send your $utxo to your $recipient ``` -$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0795 }''') +$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0004 }''') $ echo $rawtxhex -0100000001720e9d33eaf2b60e631c71bf59838f3a308ba4d1c394ba4e24f67162670598ee0000000000ffffffff01b04e7900000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` -### Understand the Transaction Fee - -You'll note that we didn't send the whole .08 BTC to our recipient. That's because of the transaction fee, which is _implicit_ when you send a raw transaction: the amount that you will pay as a fee is always equal to the amount of your input minus the amount of your output. So, you have to decrease your output a little bit from your input to make sure that your transaction goes out. - -> :warning: **WARNING:** This is the very dangerous part of raw transactions!! Because you automatically expend all of the amount in the UTXOs that you use, it's critically important to make sure that you know: (1) precisely what UTXOs you're using; (2) exactly how much money they contain; (3) exactly how much money you're sending out; and (4) what the difference is. If you mess up and you use the wrong UTXO (with more money than you thought) or if you send out too little money, the excess is lost. Forever. Don't make that mistake! Know your inputs and outputs _precisely_. Or better, don't use raw transactions except as part of a carefully considered and triple-checked program. - -_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 220 satoshis/byte" and that "For the median transaction size of 226 bytes, this results in a fee of 49,720 satoshis". - -That basic info is what we used to construct our raw transaction. We just subtracted 50,000 satoshis, which is .0005 BTC, from the amount we were sending: .0800 BTC - .0005 BC= .0795, which is what we sent. (Often transactions don't need to be the "fastest" and can get away with much lower transaction fees; we opted not to because we don't want to delay working through this tutorial.) - -> :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. - ### Verify Your Raw Transaction You should next verify your rawtransaction with `decoderawtransaction` to make sure that it will do the right thing. ``` $ bitcoin-cli decoderawtransaction $rawtxhex { - "txid": "6d39d612fe382eaab9897d3ea4d5e44233d8acef40e63fe0f06df785fd7a0c45", - "hash": "6d39d612fe382eaab9897d3ea4d5e44233d8acef40e63fe0f06df785fd7a0c45", + "txid": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "hash": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "version": 2, "size": 85, "vsize": 85, - "version": 1, + "weight": 340, "locktime": 0, "vin": [ { - "txid": "ee9805676271f6244eba94c3d1a48b303a8f8359bf711c630eb6f2ea339d0e72", - "vout": 0, + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, "scriptSig": { "asm": "", "hex": "" @@ -157,7 +165,7 @@ $ bitcoin-cli decoderawtransaction $rawtxhex ], "vout": [ { - "value": 0.07950000, + "value": 0.00040000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", @@ -172,7 +180,8 @@ $ bitcoin-cli decoderawtransaction $rawtxhex ] } ``` -Check the `vin`. Are you spending the right transaction? Does it contain the expected amount of money? Check your vout. Are you sending the right amount? Is it going to the right address? Finally, do the math to make sure the money balances. Does the value of the UTXO minus the amount being spent equal the expected transaction fee? + +Check the `vin`. Are you spending the right transaction? Does it contain the expected amount of money? (Check with `bitcoin-cli gettransaction` and be sure to look at the right `vout`.) Check your `vout`. Are you sending the right amount? Is it going to the right address? Finally, do the math to make sure the money balances. Does the value of the UTXO minus the amount being spent equal the expected transaction fee? > :information_source: **NOTE - SEQUENCE:** You may note that each input has a sequence number, set here to 4294967295, which is 0xFFFFFFFF. This is the last frontier of Bitcoin transactions, because it's a standard field in transactions that was originally intended for a specific purpose, but was never fully implemented. So now there's this integer sitting around in transactions that could be repurposed for other uses. And, in fact, it has been. As of this writing there are three different uses for the variable that's called `nSequence` in the Bitcoin Core code: it enables RBF, `nLockTime`, and relative timelocks. If there's nothing weird going on, `nSequence` will be set to 4294967295. Setting it to a lower value signals that special stuff is going on. @@ -185,10 +194,10 @@ First, you need to sign your raw transaction: $ bitcoin-cli signrawtransactionwithwallet $rawtxhex { - "hex": "0100000001720e9d33eaf2b60e631c71bf59838f3a308ba4d1c394ba4e24f67162670598ee000000006b483045022100d8f17dadc2501596f75f2c90b8279130e588638d4f7a4f7d5ebb10fea15252f702200ceb164e81335c430893780d06cfe194c36acec26886f180408e3ac4a7d2292f0121035de6239e70523c8f392e32f98e65f6ef704c4b6b0df994e407212b839bf51048ffffffff01b04e7900000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", "complete": true } -$ signedtx="0100000001720e9d33eaf2b60e631c71bf59838f3a308ba4d1c394ba4e24f67162670598ee000000006b483045022100d8f17dadc2501596f75f2c90b8279130e588638d4f7a4f7d5ebb10fea15252f702200ceb164e81335c430893780d06cfe194c36acec26886f180408e3ac4a7d2292f0121035de6239e70523c8f392e32f98e65f6ef704c4b6b0df994e407212b839bf51048ffffffff01b04e7900000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" +$ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" ``` Note that we captured the signed hex by hand, rather than trying to parse it out of the JSON object. A software package called "JQ" could do better, as we'll explain in an upcoming interlude. @@ -197,61 +206,63 @@ Note that we captured the signed hex by hand, rather than trying to parse it out You've now got a ready-to-go raw transaction, but it doesn't count until you actually put it on the network, which you do with the `sendrawtransaction` command. You'll get back a txid: ``` $ bitcoin-cli sendrawtransaction $signedtx -bf02068e3d2a99542c6a9ad07d915f1664374e911d809afe156dbacc46a5183e +a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a ``` -You'll immediately see that the UTXO and its money have been removed from your account: +You'll immediately see that the UTXO and its money have been removed from your wallet: ``` $ bitcoin-cli listunspent [ { - "txid": "c1abb6951e6a9aae7e384412b69b69e59c10daac9397d01d0c52b7bc6278d589", - "vout": 1, - "address": "mygxipnJUsBgFvscKAaoxDdE8aCmHhRfTZ", - "account": "", - "scriptPubKey": "76a914c756c7bd67bf83d83c04e3dc6fd1ff0c6fe8ea9888ac", - "amount": 0.07800000, - "confirmations": 12, + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 23, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true }, { - "txid": "ab7ca727055b812df882298f4e6e10ec699fb6250d843c813623171781f896d8", + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", "vout": 0, - "address": "mygxipnJUsBgFvscKAaoxDdE8aCmHhRfTZ", - "account": "", - "scriptPubKey": "76a914c756c7bd67bf83d83c04e3dc6fd1ff0c6fe8ea9888ac", - "amount": 0.07800000, - "confirmations": 12, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 6, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true } ] + $ bitcoin-cli getbalance -0.15600000 +0.00032000 ``` Soon `listtransactions` should show a confirmed transaction of category 'send". ``` { - "account": "", "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", "category": "send", - "amount": -0.07950000, + "amount": -0.00040000, "vout": 0, - "fee": -0.00050000, + "fee": -0.00010000, "confirmations": 1, - "blockhash": "0000000000000dd6f6f455be7eecaf8055bb61d5d18d142d75bcdf8aa6d81456", - "blockindex": 3, - "blocktime": 1488410944, - "txid": "bf02068e3d2a99542c6a9ad07d915f1664374e911d809afe156dbacc46a5183e", + "trusted": true, + "txid": "a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a", "walletconflicts": [ ], - "time": 1488410872, - "timereceived": 1488410872, + "time": 1592608574, + "timereceived": 1592608574, "bip125-replaceable": "no", "abandoned": false } ``` -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. +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. Congratulations! You're now a few satoshis poorer! From 77f5d6c4fd2e2d4ebf93248059599643ab0d2ae2 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:03:52 -1000 Subject: [PATCH 050/202] Update 04_2__Interlude_Using_JQ.md --- 04_2__Interlude_Using_JQ.md | 101 +++++++++++++++++------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/04_2__Interlude_Using_JQ.md b/04_2__Interlude_Using_JQ.md index ff6d3e3..fbe3346 100644 --- a/04_2__Interlude_Using_JQ.md +++ b/04_2__Interlude_Using_JQ.md @@ -13,7 +13,7 @@ Once you've downloaded the binary, you can install it on your system. If you're $ mv jq-linux64 jq $ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq ``` -_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." +> :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 @@ -23,7 +23,7 @@ In the previous section, the use of `signrawtransaction` offered an example of n ``` $ bitcoin-cli signrawtransactionwithwallet $rawtxhex { - "hex": "0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", "complete": true } ``` @@ -34,17 +34,17 @@ To use JQ, run `jq` at the backend of a pipe, and always use the standard invoca To capture a specific value from a JSON object, you just list the key after the `.`: ``` $ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' -0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` With that tool in hand, you can capture information from JSON objects to command-line variables: ``` $ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') $ echo $signedtx -0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` You can then use those variables easily and without error: ``` -$ bitcoin-cli sendrawtransactionwithwallet $signedtx +$ bitcoin-cli sendrawtransaction $signedtx 3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 ``` ## Use JQ to Access Single JSON Object Values in an Array by Key @@ -53,38 +53,40 @@ $ bitcoin-cli sendrawtransactionwithwallet $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 first of them. You use `'.[0]'` 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 first element. The `[]` says that we're referencing a JSON array and the `0` says we want the 0th index. ``` -$ bitcoin-cli listunspent | jq -r '.[0]' +$ bitcoin-cli listunspent | jq -r '.[1]' { - "txid": "2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708", - "vout": 1, - "address": "mjtEqr4Fffd1XtpAkKoDkMBP54mMXJeQ3j", - "account": "", - "scriptPubKey": "76a9142fe70d51e886b9ef73b76c1743c5a2bb2894db8588ac", - "amount": 0.76, - "confirmations": 6578, + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 9, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "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`: ``` -$ bitcoin-cli listunspent | jq -r '.[0] | .txid' -2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708 +$ bitcoin-cli listunspent | jq -r '.[1] | .txid' +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c ``` Carefully note how the `' 's` go around the whole JQ expression _including_ the pipe. This method can be used to fill in variables for a UTXO that you want to use: ``` -$ newtxid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') -$ newvout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ newtxid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ newvout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') $ echo $newtxid -2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708 +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c $ echo $newvout -1 +0 ``` -Voila! We could now create a new raw transaction using our 0th UTXO as an input, without having to type in any of the UTXO info by hand! +Voila! We could now create a new raw transaction using our 1st UTXO as an input, without having to type in any of the UTXO info by hand! ## Use JQ to Access Matching JSON Object Values in an Array by Key @@ -93,9 +95,8 @@ Voila! We could now create a new raw transaction using our 0th UTXO as an input, Instead of accessing a single, specific value in a specific JSON object, you could instead access all of a specific value across all the JSON objects. This is done with `.[]`, where no index is specified. For example, this would list all unspent funds: ``` $ bitcoin-cli listunspent | jq -r '.[] | .amount' -0.76 -3.9 -1.95 +0.0001 +0.00022 ``` ## Use JQ for Simple Calculations by Key @@ -105,9 +106,9 @@ $ bitcoin-cli listunspent | jq -r '.[] | .amount' At this point, you can start using JQ output for simple math. For example, adding up the values of those unspent transactions with a simple `awk` script would give you the equivalent of `getbalance`: ``` $ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}' -6.61 +0.00032 $ bitcoin-cli getbalance -6.61000000 +0.00032000 ``` ## Use JQ to Display Multiple JSON Object Values in an Array by Multiple Keys @@ -119,15 +120,12 @@ JQ can easily capture individual elements from JSON objects and arrays and place For example, you might want to see a listing of all your UTXOs (`.[]`) and get a listing of all of their most important information (`.txid, .vout, .amount`): ``` $ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount' -2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708 -1 -0.76 -ec0598918f6f5476cb90365651e8a2724ef26f949290bbf196f41ed96092a52f +ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 0 -3.9 -3470e5fe08633583d136b9cd49bb1a224c9d9313a0b4584fd3b7438dbdf34dbd +0.0001 +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c 0 -1.95 +0.00022 ``` This makes it easy to decide which UTXOs to spend in a raw transaction, but it's not very pretty. @@ -137,38 +135,28 @@ The following example shows the exact same parsing of `listunspent`, but with th ``` $ bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }' { - "txid": "2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708", - "vout": 1, - "amount": 0.76 + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "amount": 0.0001 } { - "txid": "ec0598918f6f5476cb90365651e8a2724ef26f949290bbf196f41ed96092a52f", + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", "vout": 0, - "amount": 3.9 -} -{ - "txid": "3470e5fe08633583d136b9cd49bb1a224c9d9313a0b4584fd3b7438dbdf34dbd", - "vout": 0, - "amount": 1.95 + "amount": 0.00022 } ``` You could of course rename your new keys as you see fit. There's nothing magic in the original names: ``` $ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .amount }' { - "tx": "2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708", - "output": 1, - "bitcoins": 0.76 + "tx": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "output": 0, + "bitcoins": 0.0001 } { - "tx": "ec0598918f6f5476cb90365651e8a2724ef26f949290bbf196f41ed96092a52f", + "tx": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", "output": 0, - "bitcoins": 3.9 -} -{ - "tx": "3470e5fe08633583d136b9cd49bb1a224c9d9313a0b4584fd3b7438dbdf34dbd", - "output": 0, - "bitcoins": 1.95 + "bitcoins": 0.00022 } ``` ## Use JQ to Access JSON Objects by Looked-Up Value @@ -369,6 +357,11 @@ $ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk ``` To complete the transaction fee calculation, you subtract the .vout .amount (1.045) from the .vin .amount (1.3). +To do this, you'll need to install `bc`: +``` +$ sudo apt-get intall bc +``` + Putting it all together creates a complete calculator in just five lines of script: ``` $ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) From 2a17f003bab8744af61f51ea86f3b3735b34ebc6 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:04:41 -1000 Subject: [PATCH 051/202] Update TODO.md --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 2c71e18..d55b1a8 100644 --- a/TODO.md +++ b/TODO.md @@ -24,6 +24,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Re-edit Chapter 2 **6/19** * Edit & Check Chapter 3 **6/19** * Edit & Check Chapter 4 + * Double-check fee calculator in 4.2I with a more complex example * Edit & Check Chapter 5 * Edit & Check Chapter 6 From ee3499ccb447290a9450cd0849110a6de88a3484 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:17:22 -1000 Subject: [PATCH 052/202] updated examples --- ..._a_Raw_Transaction_with_Named_Arguments.md | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md b/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md index 09ab265..b3fa2a0 100644 --- a/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md +++ b/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md @@ -20,9 +20,10 @@ To learn what the names are for the arguments of a command, consult `bitcoin-cli For example, `bitcoin-cli help getbalance` lists these arguments: - 1. account + 1. dummy [used to be account] 2. minconf - 3. include watchonly + 3. include_watchonly + 4. avoid_reuse The following shows a traditional, unintuitive usage of `getbalance` using the minimum confirmation argument: ``` @@ -30,7 +31,7 @@ $ bitcoin-cli getbalance "*" 1 ``` With named arguments, you can clarify what you're doing, which also minimizes mistakes: ``` -$ bitcoin-cli -named getbalance account="*" minconf=1 +$ bitcoin-cli -named getbalance minconf=1 ``` ## Test Out a Raw Transaction @@ -41,19 +42,20 @@ $ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') $ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.7595 }''') +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00001 }''') $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex { - "txid": "f445f121085d98635f7302e641f815d1ca4ce70f0e1b03f144ad1661dc5e10e7", - "hash": "f445f121085d98635f7302e641f815d1ca4ce70f0e1b03f144ad1661dc5e10e7", + "txid": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "hash": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "version": 2, "size": 85, "vsize": 85, - "version": 2, + "weight": 340, "locktime": 0, "vin": [ { - "txid": "2b5f5798359e0e23e02764588166f222d4ce056419dec83c743b72aad171d708", - "vout": 1, + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, "scriptSig": { "asm": "", "hex": "" @@ -63,7 +65,7 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex ], "vout": [ { - "value": 0.75950000, + "value": 0.00001000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", @@ -80,7 +82,7 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx -8000dca7b1e7ab70f4056bc4512af6ffff7727d1588436521da3e5d886dbcddf +e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172 ``` Voila! You've sent out another raw transaction, but this time using named arguments for clarity and to reduce errors. From c909598a2820448fbe86a76c7f92c745e84f8d82 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:32:08 -1000 Subject: [PATCH 053/202] updating examples --- 04_4_Sending_Coins_with_a_Raw_Transaction.md | 99 ++++++++++++-------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/04_4_Sending_Coins_with_a_Raw_Transaction.md b/04_4_Sending_Coins_with_a_Raw_Transaction.md index 6ed11b3..c12cbd5 100644 --- a/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -8,13 +8,13 @@ We can now put those together and actually send funds using a raw transaction. ## Create a Change Address -Our sample raw transaction in section 4.2 was very simplistic: we sent the entirety of a UTXO to a new address. More frequently, you'll want to send someone an amount of money that doesn't match a UTXO. But, you'll recall that the excess money from a UTXO that's not sent to your recipient just becomes a transaction fee. So, how do you send someone just part of a UTXO, while keeping the rest for yourself? +Our sample raw transaction in section §4.2 was very simplistic: we sent the entirety of a UTXO to a new address. More frequently, you'll want to send someone an amount of money that doesn't match a UTXO. But, you'll recall that the excess money from a UTXO that's not sent to your recipient just becomes a transaction fee. So, how do you send someone just part of a UTXO, while keeping the rest for yourself? The solution is to _send_ the rest of the funds to a second address, a change address that you've created in your wallet specifically to receive them: ``` -$ changeaddress=$(bitcoin-cli getrawchangeaddress) +$ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) $ echo $changeaddress -myrK8U3SE1nWh9y9XPho5aTrKYW6n8qSQv +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h ``` Note that this uses a new function: `getrawchangeaddress`. It's largely the same as `getnewaddress` but is optimized for use as a change address in a raw transaction, so it doesn't do things like make entries in your address book. @@ -28,52 +28,70 @@ Our sample raw transaction was simple in another way: it assumed that there was To summarize: creating a real raw transaction to send coins will sometimes require multiple inputs and will almost always require multiple outputs, one of which is a change address. We'll be creating that sort of more realistic transaction here, in a new example that shows a real-life example of sending funds via Bitcoin's second methodology, raw transactions. -Here's the UTXOs we'll be using: +We're going to use our 0th and 2nd UTXOs: ``` $ bitcoin-cli listunspent +[ [ { - "txid": "ec0598918f6f5476cb90365651e8a2724ef26f949290bbf196f41ed96092a52f", - "vout": 0, - "address": "mjtEqr4Fffd1XtpAkKoDkMBP54mMXJeQ3j", - "account": "", - "scriptPubKey": "76a9142fe70d51e886b9ef73b76c1743c5a2bb2894db8588ac", - "amount": 3.90000000, - "confirmations": 9551, + "txid": "0619fecf6b2668fab1308fbd7b291ac210932602a6ac6b8cc11c7ae22c43701e", + "vout": 1, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00899999, + "confirmations": 1, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true }, { - "txid": "3470e5fe08633583d136b9cd49bb1a224c9d9313a0b4584fd3b7438dbdf34dbd", + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", "vout": 0, - "address": "msiyutru5TV33Q2UGK2Bbh2ewdrYALBzTb", - "account": "", - "scriptPubKey": "76a91485e7d9fe99708d575f3b93be13c0c55c6ffb765088ac", - "amount": 1.95000000, - "confirmations": 9542, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, "spendable": true, - "solvable": true - } + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "0df23a9dba49e822bbc558f15516f33021a64a5c2e48962cec541e0bcc79854d", + "vout": 0, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00100000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + } ] ``` -In our example, we're going to send 4.0 BTC, which is larger than either of our UTXOs. This requires combining them, then using our change address to retrieve the unspent funds. +In our example, we're going to send .009 BTC, which is (barely) larger than either of our UTXOs. This requires combining them, then using our change address to retrieve the unspent funds. ### Set Up Your Variables We already have `$changeaddress` and `$recipient` variables from previous examples: ``` $ echo $changeaddress -myrK8U3SE1nWh9y9XPho5aTrKYW6n8qSQv -~$ echo $recipient +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +$ echo $recipient n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi ``` We also need to record the txid and vout for each of our two UTXOs. Having identified the UTXOs that we want to spend, we can use our JQ techniques to make sure accessing them is error free: ``` $ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') $ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') -$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') -$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') ``` ### Write the Transaction @@ -82,14 +100,14 @@ Writing the actual raw transaction is surprisingly simple. All you need to do is Here's the example. Note the multiple inputs after the `inputs` arg and the multiple outputs after the `outputs` arg. ``` -$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 4.0, "'$changeaddress'": 1.8495 }''') +$ $ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') ``` -We were _very_ careful figuring out our money math. These two UTXOs contain 5.85 BTC. After sending 4.0 BTC, we'll have 1.85 BTC left. We again chose .0005 BTC for the transaction fee. To accommodate that fee, we set our change to 1.8495 BTC. If we'd messed up our math and instead set our change to 1.7495 BTC, that additional .1 BTC would be lost. That's $100 gone to the miners! If we'd forgot to make change at all, then the whole 1.85 BTC ($2000!) would have disappeared. So, again, _be careful_. +We were _very_ careful figuring out our money math. These two UTXOs contain 5.85 BTC. After sending 0.009 BTC, we'll have .00099999 BTC left. We chose .00009999 BTC the transaction fee. To accommodate that fee, we set our change to .0009 BTC. If we'd messed up our math and instead set our change to .00009 BTC, that additional BTC would be lost to the miners! If we'd forgot to make change at all, then the whole excess would have disappeared. So, again, _be careful_. Fortunately, we can triple-check with the `btctxfee` alias from the JQ Interlude: ``` -$ btctxfee $rawtxhex2 -.0005 +$ ./txfee-calc.sh $rawtxhex2 +.00009999 ``` ### Finish It Up @@ -98,31 +116,34 @@ You can now sign, seal, and deliver your transaction, and it's yours (and the fa ``` $ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 -69c9ef4d1adb48596c470146ee9b60593023b6eb870b79ef666a8c9369768469 +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d ``` ### Wait As usual, your money will be in flux for a while: the change will be unavailable until the transaction actually gets confirmed and a new UTXO is given to you. -But, in 10 minutes or less (probably), you'll have your remaining money back and fully spendable again: +But, in 10 minutes or less (probably), you'll have your remaining money back and fully spendable again. For now, we're still waiting: ``` $ bitcoin-cli listunspent [ { - "txid": "69c9ef4d1adb48596c470146ee9b60593023b6eb870b79ef666a8c9369768469", - "vout": 1, - "address": "myrK8U3SE1nWh9y9XPho5aTrKYW6n8qSQv", - "scriptPubKey": "76a914c91b8f2f983aa9f8f0ba552adf6b6491ac01e02888ac", - "amount": 1.84950000, - "confirmations": 2, + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true } ] ``` -This also might be a good time to revisit a blockchain explorer, so that you can see more intuitively how the inputs, outputs, and transaction fee are all laid out: [69c9ef4d1adb48596c470146ee9b60593023b6eb870b79ef666a8c9369768469](https://live.blockcypher.com/btc-testnet/tx/69c9ef4d1adb48596c470146ee9b60593023b6eb870b79ef666a8c9369768469/). +This also might be a good time to revisit a blockchain explorer, so that you can see more intuitively how the inputs, outputs, and transaction fee are all laid out: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://live.blockcypher.com/btc-testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d/). ## Summary: Sending Coins with Raw Transactions From 608e5e2126f7a88ad8b5464be9eb651fddf452a0 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:34:18 -1000 Subject: [PATCH 054/202] Create 04_6_Creating_a_Segwit_Transaction --- 04_6_Creating_a_Segwit_Transaction | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 04_6_Creating_a_Segwit_Transaction diff --git a/04_6_Creating_a_Segwit_Transaction b/04_6_Creating_a_Segwit_Transaction new file mode 100644 index 0000000..7e74319 --- /dev/null +++ b/04_6_Creating_a_Segwit_Transaction @@ -0,0 +1,4 @@ +``` +$ bitcoin-cli getnewaddress +tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 +``` From 01a25a1ea1891ba25f6a7dfc6771d1ec8ce9aa6c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:34:42 -1000 Subject: [PATCH 055/202] Rename 04_6_Creating_a_Segwit_Transaction to 04_6_Creating_a_Segwit_Transaction.md --- ..._a_Segwit_Transaction => 04_6_Creating_a_Segwit_Transaction.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 04_6_Creating_a_Segwit_Transaction => 04_6_Creating_a_Segwit_Transaction.md (100%) diff --git a/04_6_Creating_a_Segwit_Transaction b/04_6_Creating_a_Segwit_Transaction.md similarity index 100% rename from 04_6_Creating_a_Segwit_Transaction rename to 04_6_Creating_a_Segwit_Transaction.md From c589c9f1413b5f67d356ab73cac4bc3a56bbd374 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:39:09 -1000 Subject: [PATCH 056/202] added change appearing --- 04_4_Sending_Coins_with_a_Raw_Transaction.md | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/04_4_Sending_Coins_with_a_Raw_Transaction.md b/04_4_Sending_Coins_with_a_Raw_Transaction.md index c12cbd5..2bf7966 100644 --- a/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -142,6 +142,36 @@ $ bitcoin-cli listunspent } ] ``` +And the change will eventuall arrive: +``` +[ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.00090000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 16, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` This also might be a good time to revisit a blockchain explorer, so that you can see more intuitively how the inputs, outputs, and transaction fee are all laid out: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://live.blockcypher.com/btc-testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d/). From 9f704e012569183a0877ea63072c5821ed021698 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:40:19 -1000 Subject: [PATCH 057/202] added curl link --- 04_4_Sending_Coins_with_a_Raw_Transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_4_Sending_Coins_with_a_Raw_Transaction.md b/04_4_Sending_Coins_with_a_Raw_Transaction.md index 2bf7966..93c6c2e 100644 --- a/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -187,4 +187,4 @@ _The disadvantages._ It's easy to lose money. There are no warnings, no safeguar ## What's Next? -Continue "Sending Bitcoin Transactions" with [§4.5: Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). +See another alternative way to input commands with [Interlude: Using Curl](04_4__Interlude_Using_Curl.md). From 99a73103502d82a4ec55597cb5282c31830889b8 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 14:43:13 -1000 Subject: [PATCH 058/202] Update TODO.md --- TODO.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index d55b1a8..5d673a5 100644 --- a/TODO.md +++ b/TODO.md @@ -24,7 +24,8 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Re-edit Chapter 2 **6/19** * Edit & Check Chapter 3 **6/19** * Edit & Check Chapter 4 - * Double-check fee calculator in 4.2I with a more complex example + * Double-check fee calculator in 4.2I with a more complex example **6/19** + * Interate older Curl Interlude * Edit & Check Chapter 5 * Edit & Check Chapter 6 From c8356d06f471d03344ddde90ca391485b6ef76b9 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:18:54 -1000 Subject: [PATCH 059/202] fully integrated into chapter 4 --- 04_4__Interlude_Using_Curl.md | 259 +++++++++++++++------------------- 1 file changed, 116 insertions(+), 143 deletions(-) diff --git a/04_4__Interlude_Using_Curl.md b/04_4__Interlude_Using_Curl.md index cfbea2c..fb89940 100644 --- a/04_4__Interlude_Using_Curl.md +++ b/04_4__Interlude_Using_Curl.md @@ -1,14 +1,14 @@ -_TODO: THIS NEEDS TO BE REWRITTEN TO REPOSITION THIS INTO THE FLOW OF CHAPTER 4._ - -# 12.1: Accessing Bitcoind with Curl +# Interlude: Using Curl > **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. -`bitcoin-cli`, the heart of chapters 3-6, is ultimately just a wrapper. It's a way to interface with `bitcoind` from the command line, providing simplified access to its many RPC commands. But RPC can, of course, be accessed directly. That's what this chapter is about: directly connecting to RPC with the `curl` command. +`bitcoin-cli` is ultimately just a wrapper. It's a way to interface with `bitcoind` from the command line, providing simplified access to its many RPC commands. But RPC can, of course, be accessed directly. That's what this interlude is about: directly connecting to RPC with the `curl` command. + +It won't be used much in the future chapters, but it's an important building block that you can see as an alternative access to `bitcoind` is you so prefer. ## Know Your Curl -`curl`, short for "see URL", is a command-line tool that allows you to directly access URLs in a programmatic way. It's an easy way to interact with servers like `bitcoind` that listen to ports on the internet and that speak a variety of protocols. Curl is also available as a library for many programming languages, such as C, Java, PHP, and Python. So, once you know how to work with Curl, you'll have a strong foundation for using a lot of different APIs — as we'll touch on in the next few chapters. +`curl`, short for "see URL", is a command-line tool that allows you to directly access URLs in a programmatic way. It's an easy way to interact with servers like `bitcoind` that listen to ports on the internet and that speak a variety of protocols. Curl is also available as a library for many programming languages, such as C, Java, PHP, and Python. So, once you know how to work with Curl, you'll have a strong foundation for using a lot of different API. In order to use `curl` with `bitcoind`, you must know three things: the standard format, the user name and password, and the correct port. @@ -21,21 +21,20 @@ getmininginfo Returns a json object containing mining-related information. Result: -{ - "blocks": nnn, (numeric) The current block - "currentblocksize": nnn, (numeric) The last block size - "currentblockweight": nnn, (numeric) The last block weight - "currentblocktx": nnn, (numeric) The last block transaction - "difficulty": xxx.xxxxx (numeric) The current difficulty - "errors": "..." (string) Current errors - "networkhashps": nnn, (numeric) The network hashes per second - "pooledtx": n (numeric) The size of the mempool - "chain": "xxxx", (string) current network name as defined in BIP70 (main, test, regtest) +{ (json object) + "blocks" : n, (numeric) The current block + "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + "difficulty" : n, (numeric) The current difficulty + "networkhashps" : n, (numeric) The network hashes per second + "pooledtx" : n, (numeric) The size of the mempool + "chain" : "str", (string) current network name (main, test, regtest) + "warnings" : "str" (string) any network and blockchain warnings } Examples: -> bitcoin-cli getmininginfo -> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ ``` And there's the `curl` command, at the end of the help screen! This somewhat lengthy command has four major parts: (1) a listing of your user name; (2) a `--data-binary` flag; (3) a JSON object that tells `bitcoind` what to do, including a JSON array of parameters; and (4) an HTTP header that includes the `bitcoind` URL. @@ -49,42 +48,49 @@ In order to speak with the `bitcoind` port, you need a user name and password. T For example, here's our current setup: ``` -$ more ~/.bitcoin/bitcoin.conf +$ cat ~/.bitcoin/bitcoin.conf server=1 dbcache=1536 par=1 -blocksonly=1 maxuploadtarget=137 maxconnections=16 -rpcuser=bitcoinrpc -rpcpassword=73bd45ba60ab8f9ff9846b6404769487 +rpcuser=StandUp +rpcpassword=8eaf562eaf45c33c3328bc66008f2dd1 rpcallowip=127.0.0.1 -txindex=1 +debug=tor +prune=550 testnet=1 +mintxfee=0.001 +txconfirmtarget=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 ``` -Our user name is `bitcoinrpc` and our password is `73bd45ba60ab8f9ff9846b6404769487`. +Our user name is `StandUp` and our password is `8eaf562eaf45c33c3328bc66008f2dd1`. > **WARNING:** Clearly, it's not very secure to have this information in a plain text file. As of Bitcoin Core 0.12, you can instead omit the `rpcpassword` from your `bitcoin.conf` file, and have `bitcoind` generate a new cookie whenever it starts up. The downside of this is that it makes use of RPC commands by other applications, such as the ones detailed in this chapter, more difficult. So, we're going to stick with the plain `rpcuser` and `rpcpassword` information for now, but for production software, consider moving to cookies. The secure way to RPC with `bitcoind` is as follows: ``` -$ curl --user bitcoinrpc --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +$ curl --user StandUp --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ Enter host password for user 'bitcoinrpc': ``` As noted, you will be prompted for your password. +> :link: **TESTNET vs MAINNET:** Testnet uses a URL with port 18332 and mainnet uses a URL with port 8332. Take a look in your `bitcoin.conf`, it's all laid out there. + The insecure way to do so is as follows: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +$ 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/ ``` > **WARNING:** Entering your password on the command line may put your password into the process table and/or save it into a history. This is even less recommended than putting it in a file, except for testing on testnet. If you want to do it anywhere else, make sure you know what you're doing! -### Know Your Port - -The port should be easy, it's the `http://127.0.0.1:8332/` shown in the tutorials, right? Not exactly. It depends on whether you're using testnet or mainnet. - -> **MAINNET VS. TESTNET.** To access RPC commands on the mainnet, use port 8332, but to do so on testnet, use port 18332. - ### Know Your Command & Parameters With all of that in hand, you're ready to send off standard RPC commands with `curl` ... but you still need to know how to incorporate the two elements that tend to change in the `curl` command. @@ -99,38 +105,33 @@ Here's what some parameter arrays will look like: * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — An array with data * `["'$signedhex'"]` — An array with a variable * `[6, 9999999]` — An array with two parameters + * `{}` - An empty object * `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` — An array with an array containing an object and a bare object ## Get Information You can now send your first `curl` command by accessing the `getmininginfo` RPC: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ -{"result":{"blocks":1128599,"currentblocksize":0,"currentblockweight":0,"currentblocktx":0,"difficulty":1,"errors":"Warning: unknown new rules activated (versionbit 28)","networkhashps":8658807967387.751,"pooledtx":0,"chain":"test"},"error":null,"id":"curltest"} -``` +$ 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. - +``` > **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`: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' - -% Total % Received % Xferd Average Speed Time Time Time Current +$ 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/ | jq -r '.' + % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed -100 354 100 277 100 77 65546 18220 --:--:-- --:--:-- --:--:-- 92333 - +100 295 100 218 100 77 72666 25666 --:--:-- --:--:-- --:--:-- 98333 { "result": { - "blocks": 1128609, - "currentblocksize": 0, - "currentblockweight": 0, - "currentblocktx": 0, - "difficulty": 2777757.750498331, - "errors": "Warning: unknown new rules activated (versionbit 28)", - "networkhashps": 8795436830406.6, - "pooledtx": 0, - "chain": "test" + "blocks": 1772429, + "difficulty": 10178811.40698772, + "networkhashps": 90580030969896.44, + "pooledtx": 4, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" }, "error": null, "id": "curltest" @@ -144,32 +145,35 @@ Though you're accessing `bitcoind` directly, you'll still get access to wallet f ### Look Up Addresses -Use the `getaddressesbyaccount` RPC to list all of your current addresses: +Use the `getaddressesbylabel` RPC to list all of your current addresses: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' - - { - "result": [ - "mg7YqyvK8HUFvpgZ5iYTfZ5vjfaJWnNTd9", - "mkMkhbUzcSPdEHUoRQkBKHe8otP1SzWWeb", - "moXjRArk4rWUYZvAiDHnMXQHmwyf3TtAb8", - "mp3qqSTEYqhm3iuo9nM5GnzCGuoEvb9KrK", - "msW5tzCMJRECSATENN11ATmxx3PLwjGEaW", - "msZ5bMbZC4HQPRuJCoivDWYExAB7ssE5o8", - "mx3wUEVp526gkqzMteK6NwsPffgtFB3CGX", - "mxwLPpo2X1VXXAiLHNVb55H4JASeLMDm7A", - "n2AfUVXq9MzsJohCjCKNXKj2SYHfdbrcqy", - "n2fGxDXKozkZjpi9DqW93NZ65TnQDqd49V", - "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf", - "2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8", - "2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz", - "2NDx9HTeLagiEqWrYvBuPkG3gwdhQ32Jz4B" - ], +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": { + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE": { + "purpose": "receive" + }, + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff": { + "purpose": "receive" + }, + "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B": { + "purpose": "receive" + }, + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d": { + "purpose": "receive" + }, + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6": { + "purpose": "receive" + }, + "tb1qmtucvjtga68kgrvkl7q05x4t9lylxhku7kqdpr": { + "purpose": "receive" + } + }, "error": null, "id": "curltest" } ``` -This is our first example of a real parameter, `""`. This is the required `account` parameter for `getaddressbyaccount`, but all of our addresses are in the default account, so nothing special was required here. +This is our first example of a real parameter, `""`. This is the required `label` parameter for `getaddressesbylabel`, but all of our addresses are under the default label, so nothing special was required here. The result is a list of all the addresses that have been used by this wallet ... some of which presumably contain funds. @@ -177,64 +181,33 @@ The result is a list of all the addresses that have been used by this wallet ... Use the `listunspent` RPC to list the funds that you have available: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' - +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' { "result": [ { - "txid": "6a184a2f07fa30189f4831d6f041d52653a103b3883d2bec2f79187331fd7f0e", - "vout": 0, - "address": "mnsdQUxpGa6UsroUJhJGupPrPcuvQbPzmV", - "scriptPubKey": "76a91450b1d90a130c4f3f1e5fbfa7320fd36b7265db0488ac", - "amount": 1.2985, - "confirmations": 1260, + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.0009, + "confirmations": 4, "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true }, { - "txid": "966099e0fd330007eac0394d97a36985980ff971d64b865c5d474f1931eeec3a", + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", "vout": 0, - "address": "2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz", - "account": "", - "scriptPubKey": "a914babf9063cee8ab6e9334f95f6d4e9148d0e551c287", - "amount": 1.2985, - "confirmations": 3681, - "spendable": false, - "solvable": false - }, - { - "txid": "e31f747cb97a364a1a00b56a3d9d43a97c6e02938a47e599ad54d7cf710f056f", - "vout": 0, - "address": "2NDx9HTeLagiEqWrYvBuPkG3gwdhQ32Jz4B", - "account": "", - "redeemScript": "52210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd81921029bf628adf0698a089137294975c8589cf0cc6be050f92d944faaa8c8a623430352ae", - "scriptPubKey": "a914e31fa4be1f718e068ba5cbb2f12a59bba66a2da687", - "amount": 1.3, - "confirmations": 6515, - "spendable": false, - "solvable": true - }, - { - "txid": "88e5d5f3077517d76f5a61491fa52e6aaae078c52bc62d849f09507ef0cfada2", - "vout": 0, - "address": "n4cqjJE6fqcmeWpftygwPoKMMDva6BpyHf", - "account": "", - "scriptPubKey": "76a914fd67e8a7c7813e7a5c376eb71074f373d924d96888ac", - "amount": 0.47, - "confirmations": 38043, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 19, "spendable": true, - "solvable": true - }, - { - "txid": "7e8abac5040a14f74fc8c44300c89cf93ce7f59f1e1c1d1711fdddd7012941c1", - "vout": 0, - "address": "moXjRArk4rWUYZvAiDHnMXQHmwyf3TtAb8", - "account": "", - "scriptPubKey": "76a91457e6ac3cfbc9c34c292ca59f105a2d7a819db7a488ac", - "amount": 0.65, - "confirmations": 6586, - "spendable": true, - "solvable": true + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true } ], "error": null, @@ -247,20 +220,19 @@ This is almost exactly the same output that you receive when you type `bitcoin-c After you know where your funds are, the next step in crafting a transaction is to get a change address. By now you've probably got the hang of this, and you know that for simple RPC commands, all you need to do is adjust the `method` is the `curl` command: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' - - { - "result": "mznccEt2ozGFN6oVaYU5BGgTzcdH8Zj8wf", +$ 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": "mrSqN37TPs89GcidSZTvXmMzjxoJZ6RKoz", "error": null, "id": "curltest" } + ``` At this point, we can even revert to our standard practice of saving results to variables with additional help from `jq`: ``` -$ changeaddress=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') - +$ 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 -mmDWRH3CbeXwCqBwdHCj7E9d3oWTuuizxc +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. @@ -274,29 +246,28 @@ Just as with `bitcoin-cli`, in order to create a transaction by curling RPC comm This example sets up our variables for using the 1.2985 BTC in funds listed in the first unspent transaction above: ``` -$ utxo_txid=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') -$ utxo_vout=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') +$ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') +$ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') $ recipient=mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf -$ changeaddress=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +$ 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 $utxo_txid -6a184a2f07fa30189f4831d6f041d52653a103b3883d2bec2f79187331fd7f0e +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d $ echo $utxo_vout -0 +1 $ echo $recipient mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf $ echo $changeaddress -mmDWRH3CbeXwCqBwdHCj7E9d3oWTuuizxc +n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N ``` ### Create the Transaction The transaction created with `curl` is very similar to the transaction created with `bitcoin-cli`, but with a few subtle differences: ``` -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' - - { - "result": "02000000010e7ffd317318792fec2b3d88b303a15326d541f0d631489f1830fa072f4a186a0000000000ffffffff0240b6c601000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac00e1f505000000001976a9143e84156731d67c80c3dff6c1cc3b4f58460e642388ac00000000", +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "02000000010d6acd0356db222ca3a7ee7fa1e3044316223ceec1f64b58aeb2e0de921007e70100000000ffffffff0230750000000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac50c30000000000001976a9147021efec134057043386decfaa6a6aa4ee5f19eb88ac00000000", "error": null, "id": "curltest" } @@ -313,7 +284,7 @@ However, there's one last thing of note in this example, and it can be _maddenin Having verified that things work, you probably want to save the hex code into a variable: ``` -$ hexcode=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +$ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') ``` ### Sign and Send @@ -321,17 +292,19 @@ $ hexcode=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binar Signing and sending your transaction using `curl` is an easy use of the `signrawtransactionwithwallet` and `sendrawtransaction` RPC: ``` -$ signedhex=$(curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex') +$ signedhex=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex') -$ curl --user bitcoinrpc:73bd45ba60ab8f9ff9846b6404769487 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' { - "result": "000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2", + "result": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", "error": null, "id": "curltest" } ``` ## Summary: Accessing Bitcoind with Curl -Having finished this section, you may feel that accessing `bitcoind` via `curl` is very much like accessing it through `bitcoin-cli` ... but more cumbersome. And, you'd be right. `bitcoin-cli` has pretty complete RPC functionality, so anything that you do through `curl` you can probably do through `bitcoin-cli`. +Having finished this section, you may feel that accessing `bitcoind` via `curl` is very much like accessing it through `bitcoin-cli` ... but more cumbersome. And, you'd be right. `bitcoin-cli` has pretty complete RPC functionality, so anything that you do through `curl` you can probably do through `bitcoin-cli`. Which is why we're going to continue concentrating on `bitcoin-cli` following this digression. -_What is the power of curl?_ Most obviously, `curl` takes out one level of indirection. Instead of working with `bitcoin-cli` which sends RPC commands to `bitcoind`, you're sending those RPC commands directly. This allows for more robust programming, because you don't have to worry about what unexpected things that `bitcoin-cli` might do or how it might change over time. However, you're also taking your first steps toward using a more comprehensive programming language than the poor options offered by a shell script. But for that, you'll need to use a `curl` library within a more familiar language like C. In other words, command-line `curl` was just the first step, the basis to better explain what you're doing as you move forward. +But there are still reasons you'd use `curl` instead of `bitcoin-cli`: + +_What is the power of curl?_ Most obviously, `curl` takes out one level of indirection. Instead of working with `bitcoin-cli` which sends RPC commands to `bitcoind`, you're sending those RPC commands directly. This allows for more robust programming, because you don't have to worry about what unexpected things that `bitcoin-cli` might do or how it might change over time. However, you're also taking your first steps toward using a more comprehensive programming language than the poor options offered by a shell script. As you'll see in the last few chapters of this, you might actually see curl libraries are other functions to access the RPC commands in a variety of programming languages: but that's still a long ways away. From 25fb8d1637d6d70b4bc3e7495e03777d4368d012 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:24:02 -1000 Subject: [PATCH 060/202] Update TODO.md --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 5d673a5..593df2e 100644 --- a/TODO.md +++ b/TODO.md @@ -23,9 +23,9 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Edit Chapter 1 **6/19** * Re-edit Chapter 2 **6/19** * Edit & Check Chapter 3 **6/19** - * Edit & Check Chapter 4 + * Edit & Check Chapter 4 **4.1 through 4.4; 4.5 waiting** * Double-check fee calculator in 4.2I with a more complex example **6/19** - * Interate older Curl Interlude + * Interate older Curl Interlude **6/19** * Edit & Check Chapter 5 * Edit & Check Chapter 6 From e1f6013ab156e45b4aa99bba0888a1ee06f25f43 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:24:58 -1000 Subject: [PATCH 061/202] Update TODO.md --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 593df2e..23b0f3a 100644 --- a/TODO.md +++ b/TODO.md @@ -51,6 +51,7 @@ Add and document the following new concepts: 11. Add SegWit Transactions. The majority of Bitcoin transactions now use this signing methodology, so it needs to be fully explained and incorporated, alongside its newer bech32 addresses. * Add definitions of Segwit and bech32 addresses to 3.3 * Do we still have to use "bitcoin-cli getnewaddress "" legacy" on CLI? If not, run back through chapters that use legacy in their examples, starting in 3.3 + * Write chapter 4.6 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). 13. Add Wallet Updates. Some improvements have been made to wallet functionality, including Bitcoin Descriptors, and they should be added to the course. 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). From d99e0f326872780fdaad538ddbed89c9616c869e Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:27:23 -1000 Subject: [PATCH 062/202] adding emoji --- 04_1_Sending_Coins_The_Easy_Way.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/04_1_Sending_Coins_The_Easy_Way.md b/04_1_Sending_Coins_The_Easy_Way.md index 447a98c..7ff8d0a 100644 --- a/04_1_Sending_Coins_The_Easy_Way.md +++ b/04_1_Sending_Coins_The_Easy_Way.md @@ -91,11 +91,11 @@ While you are waiting for this transaction to clear, you'll note that `bitcoin-c To send coins the easy way, make sure your transaction defaults are rationale, get an address, and send coins there. That's why they call it easy! -### Why Use The Easy Way? +> :fire: What is the power of sending coins the easy way? -_The advantages._ It's easy. You don't have to worry about arcane things like UTXOs. You don't have to calculate transaction fees by hand, so you're not likely to make mistakes that cost you large amounts of money. If your sole goal is to sit down at your computer and send some money, this is the way to go. +> _The advantages._ It's easy. You don't have to worry about arcane things like UTXOs. You don't have to calculate transaction fees by hand, so you're not likely to make mistakes that cost you large amounts of money. If your sole goal is to sit down at your computer and send some money, this is the way to go. -_The disadvantages._ It's high level. You have very little control over what's happening, and you can't do anything fancy. If you're planning to write more complex Bitcoin software or want a deeper understanding of how Bitcoin works, then the easy way is just a dull diversion before you get to the real stuff. +> _The disadvantages._ It's high level. You have very little control over what's happening, and you can't do anything fancy. If you're planning to write more complex Bitcoin software or want a deeper understanding of how Bitcoin works, then the easy way is just a dull diversion before you get to the real stuff. ## What's Next? From 400b0b3d58a03e9e3c55e78a97923a8662175020 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:27:46 -1000 Subject: [PATCH 063/202] fire power --- 04_1_Sending_Coins_The_Easy_Way.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_1_Sending_Coins_The_Easy_Way.md b/04_1_Sending_Coins_The_Easy_Way.md index 7ff8d0a..586ea90 100644 --- a/04_1_Sending_Coins_The_Easy_Way.md +++ b/04_1_Sending_Coins_The_Easy_Way.md @@ -91,7 +91,7 @@ While you are waiting for this transaction to clear, you'll note that `bitcoin-c To send coins the easy way, make sure your transaction defaults are rationale, get an address, and send coins there. That's why they call it easy! -> :fire: What is the power of sending coins the easy way? +> :fire: ***What is the power of sending coins the easy way?*** > _The advantages._ It's easy. You don't have to worry about arcane things like UTXOs. You don't have to calculate transaction fees by hand, so you're not likely to make mistakes that cost you large amounts of money. If your sole goal is to sit down at your computer and send some money, this is the way to go. From fcb7f0528e8e8e5bcd5214fd1532783e7a243c93 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:30:34 -1000 Subject: [PATCH 064/202] updated chapter links --- 04_4_Sending_Coins_with_a_Raw_Transaction.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/04_4_Sending_Coins_with_a_Raw_Transaction.md b/04_4_Sending_Coins_with_a_Raw_Transaction.md index 93c6c2e..f869fd0 100644 --- a/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -179,12 +179,15 @@ This also might be a good time to revisit a blockchain explorer, so that you can To send coins with raw transactions, you need to create a raw transaction with one or more inputs (to have sufficient funds) and one or more outputs (to retrieve change). Then, you can follow your normal procedure of using `createrawtransaction` with named arguments and JQ, as laid out in previous sections. -### Why Use Raw Transactions +> :fire: ***What is the power of sending coins with raw transactions?*** -_The advantages._ It gives you the best control. If your goal is to write a more intricate Bitcoin script or program, you'll probably use raw transactions so that you know exactly what's going on. This is also the _safest_ situation to use raw transactions, because you can programmatically ensure that you don't make mistakes. +> _The advantages._ It gives you the best control. If your goal is to write a more intricate Bitcoin script or program, you'll probably use raw transactions so that you know exactly what's going on. This is also the _safest_ situation to use raw transactions, because you can programmatically ensure that you don't make mistakes. -_The disadvantages._ It's easy to lose money. There are no warnings, no safeguards, and no programmatic backstops unless you write them. It's also arcane. The formatting is obnoxious, even using the easy-to-use `bitcoin-cli` interface, and you have to do a lot of lookup and calculation by hand. +> _The disadvantages._ It's easy to lose money. There are no warnings, no safeguards, and no programmatic backstops unless you write them. It's also arcane. The formatting is obnoxious, even using the easy-to-use `bitcoin-cli` interface, and you have to do a lot of lookup and calculation by hand. ## What's Next? See another alternative way to input commands with [Interlude: Using Curl](04_4__Interlude_Using_Curl.md). + +Or, you prefer to skip what's frankly a digression, learn one more way to "Send Bitcoin Transactions" with [§4.5 Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). + From 4cca0158108ab6623b489410dcab68483412ff3a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:31:37 -1000 Subject: [PATCH 065/202] updated power info --- 04_5_Sending_Coins_with_Automated_Raw_Transactions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md index 22ccdd9..2bb7094 100644 --- a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -150,11 +150,11 @@ $ 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. -### Why Use Automated Raw Transactions +> :fire: ***What 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. +> _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. -_The disadvantages._ It's a hodge-podge. Though there are a few additional options for the `fundrawtransaction` command that weren't mentioned here, your control is still limited. You'd probably never want to use this method if you were writing a program where the whole goal is to know exactly what's going on. +> _The disadvantages._ It's a hodge-podge. Though there are a few additional options for the `fundrawtransaction` command that weren't mentioned here, your control is still limited. You'd probably never want to use this method if you were writing a program where the whole goal is to know exactly what's going on. ## What's Next? From 8d5b3a7dab506afbdb34243512695e7792a658e3 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:33:00 -1000 Subject: [PATCH 066/202] Update TODO.md --- TODO.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TODO.md b/TODO.md index 23b0f3a..ae975ac 100644 --- a/TODO.md +++ b/TODO.md @@ -33,10 +33,10 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip 10. Make all examples in [7.4](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_4_Testing_a_Bitcoin_Script.md) and possibly elsewhere use BTCDeb. * Edit & Integrate Chapter 7 - * Check Chapter 8 - * Check Chapter 9 - * Check Chapter 10 - * Check Chapter 11 + * Edit & Integrate Chapter 8 + * Edit & Integrate Chapter 9 + * Edit & Integrate Chapter 10 + * Edit & Integrate Chapter 11 Per @ChristopherA: From 77b284bca940f4e7863a010cbaf1e769d3ace9b9 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:34:18 -1000 Subject: [PATCH 067/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index ae975ac..91c956a 100644 --- a/TODO.md +++ b/TODO.md @@ -25,7 +25,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Edit & Check Chapter 3 **6/19** * Edit & Check Chapter 4 **4.1 through 4.4; 4.5 waiting** * Double-check fee calculator in 4.2I with a more complex example **6/19** - * Interate older Curl Interlude **6/19** + * Integrate older Curl Interlude **6/19** * Edit & Check Chapter 5 * Edit & Check Chapter 6 From d6edf937d4195c06dfa9c02bada2d4b1bc88dfe3 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Fri, 19 Jun 2020 15:34:45 -1000 Subject: [PATCH 068/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 91c956a..2bdcda4 100644 --- a/TODO.md +++ b/TODO.md @@ -18,7 +18,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip ## 2. Upgrade to 0.20 -9. Walk through chapters 1-11, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. +9. Walk through chapters 1-6, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. * Edit Chapter 0 **6/19** * Edit Chapter 1 **6/19** * Re-edit Chapter 2 **6/19** From 2b433714de680f13294ee22173d6a281adcf845b Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Sat, 20 Jun 2020 14:15:34 -0700 Subject: [PATCH 069/202] Added my own CLA, renamed folder to CLA-signed --- .../CLA.ChristopherA.F8D36C91357405ED.asc | 74 +++++++++++++++++++ .../CLA.shannona.7EC6B928606F27AD.asc | 0 2 files changed, 74 insertions(+) create mode 100644 CLA-signed/CLA.ChristopherA.F8D36C91357405ED.asc rename {signed-cla => CLA-signed}/CLA.shannona.7EC6B928606F27AD.asc (100%) diff --git a/CLA-signed/CLA.ChristopherA.F8D36C91357405ED.asc b/CLA-signed/CLA.ChristopherA.F8D36C91357405ED.asc new file mode 100644 index 0000000..09d12fc --- /dev/null +++ b/CLA-signed/CLA.ChristopherA.F8D36C91357405ED.asc @@ -0,0 +1,74 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +# Contributor License Agreement + +Version 1.0 + +Name: Christopher Allen + +E-Mail: ChristopherA@LifeWithAlacrity.com + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line + +Date: 05/19/2020 + +## 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----- + +iQIzBAEBCgAdFiEE/f4UpU7LMPxdInTv+NNskTV0Be0FAl7ue+AACgkQ+NNskTV0 +Be1G+Q//WEORFEFVG0VTFFd5yDgEs+pMNtb0ig2VXD8VB5lN9QntTXjgoVbfsdL7 +LzIVtS/rNnoxZ+e8wvKq67uG82RMm6NoCJPI6SBhF/cWdmFWIjnPL/vU/t1CJx9/ +XI52qy8xE45iNgtNncETQFoAila+0oDufmUwKTsLb8ioZ1B1NSWcUAoWaYvQkUxz +VPuSZzCzYsN+m+qwjzxVXQjqGJ4Ya5o4GpTNq32R7ajHL9kVJNf6s48mFEN6KsG5 +30pUeS9GLJH98B8jUDTJAd/Z06o+ID5Eh2dgXdBa0AcN0GeSXFp/0UEqyQcmAUFk +jn/mXS5ojBCFGguZ7mgBRo6QeHoQiAJp+bCep6Ar7X5+yMHbSi71Kk0FYSeF79xB +B7ZnIqztEal8X8UoqZmbti3m++IMcxQgVkQdcTYhES0bCtqYjewXWY5ipd16QSqh +22l49SrG7o4Sipsd+1GmBtnJCBU9CyCDDYyO52x9+V2hLN6KByyInv1YSltOR59O +0umgijDxEZ4IgiM7h6RzNIDeC1rqvHRg8oN/MprLSeU+wl49b6ijBCgfpV+n62Ht +JW//XZDfEcqIYfw5e5jTMCQAxtNijQ7W+8nBB3UOwbQRy7wC/g2mfID1GPPHou2F +OI9oM7zm4Uw0dG/VfEqvnMzMN5022gZYxsZQI00rPFIPvkYRLWY= +=zrSz +-----END PGP SIGNATURE----- diff --git a/signed-cla/CLA.shannona.7EC6B928606F27AD.asc b/CLA-signed/CLA.shannona.7EC6B928606F27AD.asc similarity index 100% rename from signed-cla/CLA.shannona.7EC6B928606F27AD.asc rename to CLA-signed/CLA.shannona.7EC6B928606F27AD.asc From a91402d9e50eabaf9e93eeb6e71ede8081ce2d59 Mon Sep 17 00:00:00 2001 From: Justin Hanneman Date: Mon, 22 Jun 2020 21:50:36 -0600 Subject: [PATCH 070/202] Avoid ambiguous (numerically-interpretable) input to btcdeb example --- 07_2_Running_a_Bitcoin_Script.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/07_2_Running_a_Bitcoin_Script.md b/07_2_Running_a_Bitcoin_Script.md index 58a1f0d..f717cff 100644 --- a/07_2_Running_a_Bitcoin_Script.md +++ b/07_2_Running_a_Bitcoin_Script.md @@ -80,7 +80,7 @@ Let's try this out: ```Bash $ btcc OP_1 OP_2 OP_ADD 515293 -$ btcdeb '[OP_1 OP_2 OP_ADD]' # or: btcdeb 515293 +$ btcdeb '[OP_1 OP_2 OP_ADD]' # or: btcdeb 0x515293 btcdeb -- type `btcdeb -h` for start up options valid script 3 op script loaded. type `help` for usage information From ca2a768ff6566b9165b8b3c62b4b652c4a001d58 Mon Sep 17 00:00:00 2001 From: Justin Hanneman Date: Mon, 22 Jun 2020 21:53:02 -0600 Subject: [PATCH 071/202] Fix minor grammatical issues in Section 8.2 intro --- 08_2_Building_the_Structure_of_P2SH.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/08_2_Building_the_Structure_of_P2SH.md b/08_2_Building_the_Structure_of_P2SH.md index d605c6a..b2383a2 100644 --- a/08_2_Building_the_Structure_of_P2SH.md +++ b/08_2_Building_the_Structure_of_P2SH.md @@ -2,7 +2,7 @@ > :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. -In the previous section we overviewed the theory of how to create P2SH transactions to hold Bitcoin Scripts. The actual practice of doing so is _much more difficult_, but for the sake of completeness, we're going to look at it here. This is probably not something you'd ever do without an API, so if it gets to intimidating, be aware that we'll returning to pristine, high-level Scripts in a moment. +In the previous section we overviewed the theory of how to create P2SH transactions to hold Bitcoin Scripts. The actual practice of doing so is _much more difficult_, but for the sake of completeness, we're going to look at it here. This is probably not something you'd ever do without an API, so if it gets too intimidating, be aware that we'll be returning to pristine, high-level Scripts in a moment. ## Create a Locking Script From 8218bbcf65c34899078bbaa75ecb2188d9c948e1 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 23 Jun 2020 19:30:53 +0200 Subject: [PATCH 072/202] Update 18_2_Accessing_Bitcoind_with_Java.md --- 18_2_Accessing_Bitcoind_with_Java.md | 268 ++++++++++++++++++++++++--- 1 file changed, 240 insertions(+), 28 deletions(-) diff --git a/18_2_Accessing_Bitcoind_with_Java.md b/18_2_Accessing_Bitcoind_with_Java.md index 0426c89..23602e8 100644 --- a/18_2_Accessing_Bitcoind_with_Java.md +++ b/18_2_Accessing_Bitcoind_with_Java.md @@ -7,39 +7,110 @@ Interacting with the `bitcoind` directly and using command-line `curl` can get s ## Setup Java -To install Java on the VPS Server, you are able to use the `apt-get` command. We will also use [Apache Maven](http://maven.apache.org/) to manage the dependencies, so we will install it together. +To install Java on the VPS Server, you are able to use the `apt-get` command. We will also use [Apache Maven](http://maven.apache.org/) to manage the dependencies, so we will install it together. In this project we will create a maven project and indicate minimum configuration about Gradle (https://gradle.org/releases/) ``` -$ apt-get install openjdk-9-jre-headless maven +$ apt-get install openjdk-11-jre-headless maven ``` You can verify your Java installation: ``` $ java -version -openjdk version "9-internal" -OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src) -OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode) +openjdk version "11.0.7" 2020-04-14 +OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu218.04) +OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-2ubuntu218.04, mixed mode, sharing) ``` -## Setup Dependency +## Create maven project + +``` +mvn archetype:generate -DgroupId=com.blockchaincommons.lbtc -DartifactId=java-project -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false +``` +It will download some dependencies + +``` +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom (4 KB at 4.2 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom (13 KB at 385.9 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/21/maven-parent-21.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/21/maven-parent-21.pom (26 KB at 559.6 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/apache/10/apache-10.pom +.............. +``` +It will create a configuration file pom.xml + +``` +user@machine:~/BitcoinRpcClient/java-project$ ll +total 16 +drwxr-xr-x 3 user user 4096 Jun 17 16:47 ./ +drwxr-xr-x 3 user user 4096 Jun 17 15:02 ../ +-rw-r--r-- 1 user user 1175 Jun 17 16:34 pom.xml +drwxr-xr-x 4 user user 4096 Jun 17 15:02 src/ +user@machine:~/BitcoinRpcClient/java-project$ +``` + +This project uses JavaBitcoindRpcClient, so you need include the dependency editing pom.xml file -If you use Maven in your Java project, you can include the dependency: ```xml wf.bitcoin JavaBitcoindRpcClient - 0.9.13 + 1.1.0 ``` +You need to add compiler properties to indicate what JDK version will compile the source code. +``` + + + UTF-8 + 1.11 + 1.11 + +``` +Finally add source code to java classes and execute + +``` +user@machine:~/BitcoinRpcClient/java-project$ mvn package +[INFO] Scanning for projects... +[INFO] +[INFO] ------------------< com.blockchaincommons.lbtc:java-project >------------------- +[INFO] Building java-project 1.0-SNAPSHOT +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +...... +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running com.blockchaincommons.lbtc.AppTest +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.067 sec + +Results : + +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 + +[INFO] +[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ java-project --- +[INFO] Building jar: /home/user/BitcoinRpcClient/java-project/target/java-project-1.0-SNAPSHOT.jar +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 1.956 s +[INFO] Finished at: 2020-06-1716T12:21:18+31:00 +[INFO] ------------------------------------------------------------------------``` + +``` Or if you use Gradle: ```groovy -compile 'wf.bitcoin:JavaBitcoindRpcClient:0.9.13' +compile 'wf.bitcoin:JavaBitcoindRpcClient:1.1.0' ``` If you want a sample project and some instructions on how to run it on the server that we just created, you can refer to the [Bitcoind Java Sample Project](https://github.com/brunocvcunha/bitcoind-java-client-sample/). -### Build Your Connection +## Build Your Connection + +### Make an RPC Call To use `JavaBitcoindRpcClient`, you need to create a `BitcoindRpcClient` instance. The arguments in the URL are username, password, IP address and port. You should know this information from your work with `curl` . 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`. @@ -79,6 +150,54 @@ Blocks.....: 1254920 Difficulty.: 1.0 Hash Power.: 6585163152453.466796875 ``` +### Making an RPC Call with Arguments + +When you make a RPC call with arguments you need to setup parameters depending method or type of object you use. + +### Look up Address + +You can look up addresses on your wallet passing it as an argument. In this case we use getAddressInfo method to obtain some information about an address. + +```java +public AddressInfo getAddressInfo(String address) throws GenericRpcException { + return new AddressInfoMapWrapper((Map) query("getaddressinfo", address)); + } + +String addr1 = "bcrt1qs4ylwj2v5v0gq7eqzp9k9vxazdrkexhkghxpyp"; //regtest +AddressInfo addr1Info = rpcClient.getAddressInfo(addr1); +System.out.println("Address: " + addr1Info.address()); +System.out.println("HdKeyPath: " + addr1Info.hdKeyPath()); +System.out.println("PubKey: " + addr1Info.pubKey()); +System.out.println("MasterFingerPrint: " + addr1Info.hdMasterFingerprint()); +``` +Output: +``` +Jun 19, 2020 8:01:56 PM wf.bitcoin.javabitcoindrpcclient.BitcoinJSONRPCClient +WARNING: Currently relying on rpcuser / rpcpassword for authentication. This will soon be deprecated in bitcoind. To use newer auth mechanism based on a temporary password, remove properties rpcuser / rpcpassword from bitcoin.conf +Address: bcrt1qs4ylwj2v5v0gq7eqzp9k9vxazdrkexhkghxpyp +HdKeyPath: m/0'/0'/16' +PubKey: 03cf852403abbcf0431e8c82b414b0c805f5e1b863989cbc9adb3a316510e0d1f5 +MasterFingerPrint: 91cfb0fc + +``` + +### Look up Funds + +You can look up your balance. + +```java +public BigDecimal getBalance(String account) throws GenericRpcException { + return (BigDecimal) query("getbalance"); + } + String balance = rpcClient.getBalance(account); + System.out.println("Balance: " + balance); + +``` +Output: + +``` +Balance: 14701.56249600 +``` ### Creating an Address @@ -98,30 +217,115 @@ New Address: mpsFtZ8qTJPRGZy1gaaUw37fHeUSPLkzzs Priv Key: cTy2AnmAALsHokYzJzTdsUBSqBtypmWfmSNYgG6qQH43euUZgqic ``` +### Create a Transaction +You can create a raw transaction using createRawTransaction method passing as arguments two ArrayList objects containing inputs and outputs to be used. In this example we will create two addresses and we will use generateToAddress method in regtest to mine some bitcoin. + +```java +public String create() throws GenericRpcException { + return bitcoin.createRawTransaction(new ArrayList<>(inputs), outputs); +} +``` + +#### generatetoaddress + +The generatetoaddress RPC mines blocks immediately to a specified address. It receives numBlocks param as the number of blocks to generate. The address to send the newly generated bitcoin to and param maxTries as the maximum number of iterations that are tried to create the requested number of blocks. + +We use generateToAddress method to mine some bitcoin and we use listUnspent (https://github.com/Polve/bitcoin-rpc-client/blob/master/src/main/java/wf/bitcoin/javabitcoindrpcclient/BitcoinJSONRPCClient.java#L756) method to load object utxos with coins associated with address object addr1. + +```java +System.out.println("Created address addr1: " + addr1); +String addr2 = rpcClient.getNewAddress(); +System.out.println("Created address addr2: " + addr2); +List generatedBlocksHashes = rpcClient.generateToAddress(110, addr1); +System.out.println("Generated " + generatedBlocksHashes.size() + " blocks for addr1"); +List utxos = rpcClient.listUnspent(0, Integer.MAX_VALUE, addr1); +System.out.println("Found " + utxos.size() + " UTXOs (unspent transaction outputs) belonging to addr1"); +``` + +debug.log +``` +2020-06-19T18:22:30Z [default wallet] AddToWallet 0bed0fc1b6190b85b93bda6fe752c7596234bea8399827d27e347f35ca68d59f new +2020-06-19T18:22:30Z CreateNewBlock(): block weight: 892 txs: 0 fees: 0 sigops 400 +2020-06-19T18:22:30Z UpdateTip: new best=6125a1648f84e11d9d8ee1b003056c20142e9f1e54376f5d117554785957aadf height=1100 version=0x20000000 log2_work=11.104599 tx=1103 date='2020-06-19T18:22:48Z' progress=1.000000 cache=0.0MiB(114txo) +2020-06-19T18:22:30Z [default wallet] AddToWallet a2690eb4c50b1140dfc77f95db9c8065e8d7e88b2cfbd9a75e9b2dd157857afd new +``` +Output +``` +Created address addr1: bcrt1qs4ylwj2v5v0gq7eqzp9k9vxazdrkexhkghxpyp +Created address addr2: bcrt1qdp6fut9pmchwacpr28vfszdp5qayza8jkq5t3v +Generated 110 blocks for addr1 +Found 118 UTXOs (unspent transaction outputs) belonging to addr1 +``` +Now we have created UXTO's we can create a transaction, to perform this we will use three objects, TxInput, TxOutput and Transactions Builder. With this code we got inputs and outputs for our transaction. Object uxto is a list with all UXTO's belonging to addr1. We will choose uxto in position zero on the list and add it to txb object as input. Then we add addr2 object as the output and set fee subtracting estimatedFee value. + +```java +BitcoinRawTxBuilder txb = new BitcoinRawTxBuilder(rpcClient); +BigDecimal estimatedFee = BigDecimal.valueOf(0.00000200); +TxInput in = utxos.get(0); +txb.in(in); + +txToAddr2Amount = utxos.get(0).amount().subtract(estimatedFee); +txb.out(addr2, txToAddr2Amount); + +System.out.println("unsignedRawTx in amount: " + utxos.get(0).amount()); +System.out.println("unsignedRawTx out amount: " + txToAddr2Amount); +``` + +Output +``` +unsignedRawTx in amount: 0.78125000 +unsignedRawTx out amount: 0.78124800 +``` ### Sending Transactions -You can easily send a transaction using the method `sendToAddress()`. +Before send a transaction we need to create and sign it. To create you can use create method of Builder Transaction object. This method returns a unsigned string transaction in hexadecimal format. + +```java +String unsignedRawTxHex = txb.create(); +System.out.println("Created unsignedRawTx from addr1 to addr2: " + unsignedRawTxHex); +``` +Output: +``` +Created unsignedRawTx from addr1 to addr2: 020000000101f08cabf817b8fb076501f04b69df0aae59d61d94edfb40c2c41b1b2bd16a3f0000000000ffffffff010017a8040000000016001468749e2ca1de2eeee02351d89809a1a03a4174f200000000 +``` +Later you should sign transaction with method signRawTransactionWithKey. This method receives as parameters a unsigned raw string transaction, the private key of address and TxInput object. + +```java +SignedRawTransaction srTx = rpcClient.signRawTransactionWithKey( + unsignedRawTxHex, + Arrays.asList(rpcClient.dumpPrivKey(addr1)), // + Arrays.asList(in), + null); +System.out.println("signedRawTx hex: " + srTx.hex()); +System.out.println("signedRawTx complete: " + srTx.complete()); +``` +Output +``` +signedRawTx hex: 0200000000010101f08cabf817b8fb076501f04b69df0aae59d61d94edfb40c2c41b1b2bd16a3f0000000000ffffffff010017a8040000000016001468749e2ca1de2eeee02351d89809a1a03a4174f20247304402204ed1ce8ea7e36cd53ba78beaccaf3ef62b094c29413a451e3abae99548520f7f02206b606c21cd38cc4e61d84c229d42ce69a01cb3a0ed360fced2a6f5b5d8dbe951012103cf852403abbcf0431e8c82b414b0c805f5e1b863989cbc9adb3a316510e0d1f500000000 +signedRawTx complete: true +``` + +Finally you can send signed transaction using + +```java +String sentRawTransactionID = rpcClient.sendRawTransaction(srTx.hex()); +System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID);``` +``` +This program will output a transaction id: + +``` +Sent signedRawTx (txID): 03b2327117264837f449a718e5aeedb07f90d435892a33c3c2772d4c3b40111f +``` +debug.log. + +``` +2020-06-19T18:22:31Z [default wallet] AddToWallet 03b2327117264837f449a718e5aeedb07f90d435892a33c3c2772d4c3b40111f new +``` + For more information about sending transactions, you can check [4: Sending Bitcoin Transactions](04_0_Sending_Bitcoin_Transactions.md). - -```java -String sendToAddress = rpcClient.sendToAddress("mgnNsZj6tPzpd7JwTTidUKnGoDTkcucLT5", 1); -System.out.println("Send: " + sendToAddress); -``` -This program will output a transaction id, for example: -``` -a2d2f629d6666ca6e440169a322850cd9d133f637f7a02a02a0a7477bc5687d4 -``` - -In case you want to adjust the transaction fee, you can use the `setTxFee` method before sending the output: - -```java -rpcClient.setTxFee(new BigDecimal(0.001).setScale(3, BigDecimal.ROUND_DOWN)); -``` - - ### Listening to Transactions or Blocks You may want to write applications that keep listening the Blockchain, and execute a specific code when something happens, such as a transaction that involves an address in your wallet, or even the generation of a new block in the network. @@ -152,3 +356,11 @@ Transaction: {account=Tests, address=mhopuJzgmTwhGfpNLCJ9CRknugY691oXp1, categor Block: 000000004564adfee3738314549f7ca35d96c4da0afc6b232183917086b6d971 ``` + +### For More Information + +In this repository you can browse all souce code for bitcoin-rpc-client (https://github.com/Polve/bitcoin-rpc-client) + +### Summary Accessing Bitcoind with Java + +By using javabitcoinrpc library, you can easily access bitcoind via RPC calls from a Java. To do so, you should create a client, an RPC connection, then create objects and classes to interact with individual RPC calls, some of them with parameters. You can easily create address, sign transactions, query balances and others RPC methods. From f8a08873a0eb6f4f58f84dc5903663680509aca3 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:03:44 -1000 Subject: [PATCH 073/202] removed space in file name --- ...nd_with_Python .md => 18_4_Accessing_Bitcoind_with_Python.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename 18_4_Accessing_Bitcoind_with_Python .md => 18_4_Accessing_Bitcoind_with_Python.md (99%) diff --git a/18_4_Accessing_Bitcoind_with_Python .md b/18_4_Accessing_Bitcoind_with_Python.md similarity index 99% rename from 18_4_Accessing_Bitcoind_with_Python .md rename to 18_4_Accessing_Bitcoind_with_Python.md index 2d8a9d7..b51d96a 100644 --- a/18_4_Accessing_Bitcoind_with_Python .md +++ b/18_4_Accessing_Bitcoind_with_Python.md @@ -381,4 +381,4 @@ TXID of sent transaction: 'k9db702lsd512e2421915dc53clkj28f39a987c9a91cc0514faac In this chapter we learnt how to connect to a node, get some basic information about our node and even sent a transaction over testnet. Accessing Bitcoind with Python is very easy while using the `python-bitcoinrpc` library. The first thing to always do is to establish connection with your bitcoind instance then, you can basically call all the bitcoin API calls as described in the bitcoin-core documentation. This makes it really easy to create small or large scripts to manage your own node, check balances or create cool applications on top as you get the full power of `bitcoin-cli`. -All the source code for this chapter is available in the [src](./src/18_4_accessing_bitcoind_with_python.py) directory of the repo. \ No newline at end of file +All the source code for this chapter is available in the [src](./src/18_4_accessing_bitcoind_with_python.py) directory of the repo. From 6435f78eb4dd182366501306e44b97f6ce8e8874 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:04:30 -1000 Subject: [PATCH 074/202] updated ch 18 links + credits --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d214453..4b59467 100644 --- a/README.md +++ b/README.md @@ -110,12 +110,12 @@ _This tutorial assumes that you have some minimal background of how to use the c * 17.4: Integrating Libwally and Scripts * 17.0: Talking to Lightningd with C * 18.0: Talking to Bitcoind with Other Languages - * [18.1: Accessing Bitcoind with Go] - * [18.2: Accessing Bitcoind with Java](18_2_Accessing_Bitcoind_with_Java.md) — Needs Rewrite + Editing + * [18.1: Accessing Bitcoind with Go] — Unwritten + * [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) — Needs Rewrite + Editing - * [18.4: Accessing Bitcoind with Python] - * [18.5: Accessing Bitcoind with Rust] - * [18.6: Accessing Bitcoind with Swift] + * [18.4: Accessing Bitcoind with Python](18_4_Accessing_Bitcoind_with_Python.md) + * [18.5: Accessing Bitcoind with Rust] — Unwritten + * [18.6: Accessing Bitcoind with Swift] — Unwritten ### APPENDICES @@ -171,7 +171,7 @@ Additional contributions are listed below: | Role | Names | | ------------------- | ---------------------------------------- | -| ***Contributors:*** | [jodobear](https://github.com/jodobear) (Appendix I) | +| ***Contributors:*** | [javiervargas](https://github.com/javiervargas) (Java secction), [jodobear](https://github.com/jodobear) (Appendix I, Python section) | | ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) | | ***Sponsors:*** | Blockstream Corporation | From 53ffbca0411647568b7d6ff6024e8090977fba86 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:10:01 -1000 Subject: [PATCH 075/202] adjusted credit, removed curl warning --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4b59467..ba17e8e 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [Interlude: Using JQ](04_2__Interlude_Using_JQ.md) * [4.3: Creating a Raw Transaction with Named Arguments](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) * [4.4: Sending Coins with Raw Transactions](04_4_Sending_Coins_with_a_Raw_Transaction.md) - * [Interlude: Using Curl](04_4__Interlude_Using_Curl.md) — Needs Rewrite for New Section + * [Interlude: Using Curl](04_4__Interlude_Using_Curl.md) * [4.5: Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) * [4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction) — Awaiting Better Integration of Segwit into CLI * [5.0: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md) @@ -171,7 +171,7 @@ Additional contributions are listed below: | Role | Names | | ------------------- | ---------------------------------------- | -| ***Contributors:*** | [javiervargas](https://github.com/javiervargas) (Java secction), [jodobear](https://github.com/jodobear) (Appendix I, Python section) | +| ***Contributors:*** | [Javier Vargas](https://github.com/javiervargas) (Java secction), [jodobear](https://github.com/jodobear) (Appendix I, Python section) | | ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) | | ***Sponsors:*** | Blockstream Corporation | From bf4c6bd3d393bd0d5788db0ea380a903a0a27be9 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:39:17 -1000 Subject: [PATCH 076/202] added correct segwit link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba17e8e..5dd0ed4 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [4.4: Sending Coins with Raw Transactions](04_4_Sending_Coins_with_a_Raw_Transaction.md) * [Interlude: Using Curl](04_4__Interlude_Using_Curl.md) * [4.5: Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) - * [4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction) — Awaiting Better Integration of Segwit into CLI + * [4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md) — Awaiting Better Integration of Segwit into CLI * [5.0: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md) * [5.1 Watching for Stuck Transactions](05_1_Watching_for_Stuck_Transactions.md) * [5.2: Resending a Transaction with RBF](05_2_Resending_a_Transaction_with_RBF.md) From 11e1676695da7d444d201188b7ba659303f05f63 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:39:50 -1000 Subject: [PATCH 077/202] Update 04_6_Creating_a_Segwit_Transaction.md --- 04_6_Creating_a_Segwit_Transaction.md | 1 + 1 file changed, 1 insertion(+) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index 7e74319..27e7e25 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -2,3 +2,4 @@ $ bitcoin-cli getnewaddress tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 ``` +Advance through "bitcoin-cli" with [Chapter Five: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md). From 6272f009045386d29865eb7a3aca76dfee1f6a63 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:43:48 -1000 Subject: [PATCH 078/202] corrected examples (note: getaddressinfo), re-redited --- ...g_Coins_with_Automated_Raw_Transactions.md | 103 ++++++++++-------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md index 2bb7094..c13136f 100644 --- a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -10,7 +10,7 @@ The methodology for automated raw transactions is simple: you create a raw trans In order to use this command, you'll need to ensure that your ~/.bitcoin/bitcoin.conf file contains rational variables for calculating transaction fees. Please see [§4.1: Sending Coins The Easy Way](04_1_Sending_Coins_The_Easy_Way.md) for more information on this. -For very conservative numbers, we suggested adding the following to the bitcoin.conf: +For very conservative numbers, we suggested adding the following to the `bitcoin.conf`: ``` mintxfee=0.0001 txconfirmtarget=6 @@ -23,9 +23,10 @@ txconfirmtarget=1 ## Create a Bare Bones Raw Transaction -To use `fundrawtransaction` you first need to create a bare-bones raw transaction that lists _no_ inputs and _no_ change address. You'll just list your recipient and how much you want to send them: +To use `fundrawtransaction` you first need to create a bare-bones raw transaction that lists _no_ inputs and _no_ change address. You'll just list your recipient and how much you want to send them, in this case `$recipient` and `0.0002` BTC. ``` -$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 1.0 }''') +$ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') ``` ## Fund Your Bare Bones Transaction @@ -34,9 +35,9 @@ You then tell `bitcoin-cli` to fund that bare-bones transaction: ``` $ bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx { - "hex": "020000000169847669938c6a66ef790b87ebb6233059609bee4601476c5948db1a4defc9690100000000feffffff02a8e30f05000000001976a914a6f0ee37c44947f4137d56e4aab12f27ad50369188ac00e1f505000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", - "changepos": 0, - "fee": 0.00022600 + "hex": "02000000012db87641c6a21e5a68b20c226428544978e6ac44964d5d8060d7388000c584eb0100000000feffffff02204e0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac781e0000000000001600140cc9cdcf45d4ea17f5227a7ead52367aad10a88400000000", + "fee": 0.00022200, + "changepos": 1 } ``` That provides a lot of useful information, but once you're confident with how it works, you'll want to use JQ to save your hex to a variable, as usual: @@ -51,15 +52,16 @@ Running `decoderawtransaction` will show that the raw transaction is now laid ou ``` $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 { - "txid": "2e34603b7449d29412fb7b0d184085d4d839d965f2bba361749c20d9dbae3d0b", - "hash": "2e34603b7449d29412fb7b0d184085d4d839d965f2bba361749c20d9dbae3d0b", - "size": 119, - "vsize": 119, + "txid": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "hash": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", "version": 2, + "size": 116, + "vsize": 116, + "weight": 464, "locktime": 0, "vin": [ { - "txid": "69c9ef4d1adb48596c470146ee9b60593023b6eb870b79ef666a8c9369768469", + "txid": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", "vout": 1, "scriptSig": { "asm": "", @@ -70,21 +72,8 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 ], "vout": [ { - "value": 0.84927400, + "value": 0.00020000, "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 123cd8796558d195e52137ce3800e5f8120ee46f OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914123cd8796558d195e52137ce3800e5f8120ee46f88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "mhBPM8hU2PHjDTUvwa3SC7pqv8ExkK6mH8" - ] - } - }, - { - "value": 1.00000000, - "n": 1, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", @@ -94,30 +83,50 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" ] } + }, + { + "value": 0.00007800, + "n": 1, + "scriptPubKey": { + "asm": "0 a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "hex": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r" + ] + } } ] } ``` -We saw the fee in the more extensive output, before we saved the hex to a variable with JQ, but you can verify it with the `btctxfee` JQ alias created in the [JQ Interlude](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_2__Interlude_Using_JQ.md): +We saw the fee in the more extensive output, before we saved the hex to a variable with JQ, but 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): ``` -$ btctxfee $rawtxhex3 -.00023 +$ ~/txfee-calc.sh $rawtxhex3 +.000222 ``` -Finally, you can use `validateaddress` to see that the generated change address really belongs to you: +Finally, you can use `getaddressinfo` to see that the generated change address really belongs to you: ``` -$ bitcoin-cli -named validateaddress address=mhBPM8hU2PHjDTUvwa3SC7pqv8ExkK6mH8 +$ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r { - "isvalid": true, - "address": "mhBPM8hU2PHjDTUvwa3SC7pqv8ExkK6mH8", - "scriptPubKey": "76a914123cd8796558d195e52137ce3800e5f8120ee46f88ac", + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", "ismine": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", "iswatchonly": false, "isscript": false, - "pubkey": "029045eaa55d283526c723e6d5495d9b3f077b545563f86465aafcd9bfdd50359e",Y - "iscompressed": true, - "timestamp": 1489170694, - "hdkeypath": "m/0'/0'/11'", - "hdmasterkeyid": "144a68bde927a1fed7c2b71ad9010b0201819be5" + "iswitness": true, + "witness_version": 0, + "witness_program": "a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "pubkey": "038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5", + "ischange": true, + "timestamp": 1592335137, + "hdkeypath": "m/0'/1'/10'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + ] } ``` Note the `ismine` results. @@ -128,20 +137,23 @@ At this point you can sign and send the transaction as usual. ``` $ signedtx3=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex3 | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx3 +8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa ``` In several minutes, you'll have your change back: ``` $ bitcoin-cli listunspent [ { - "txid": "37698ad6e7f62df07c2fbc549339aa680a7fa18328d7ad14ecb72b21c505cbc6", - "vout": 0, - "address": "mhBPM8hU2PHjDTUvwa3SC7pqv8ExkK6mH8", - "scriptPubKey": "76a914123cd8796558d195e52137ce3800e5f8120ee46f88ac", - "amount": 0.84927400, + "txid": "8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa", + "vout": 1, + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "amount": 0.00007800, "confirmations": 1, "spendable": true, - "solvable": true + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "safe": true } ] ``` @@ -158,4 +170,5 @@ If you must send funds with raw transactions then `fundrawtransaction` gives you ## What's Next? -Advance through "bitcoin-cli" with [Chapter Five: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md). +Complete your "Sending of Bitcoin Transactions" with [§4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md). + From 9d2c53e89d9e8be5eb36d3861e07eb293417a677 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 08:53:47 -1000 Subject: [PATCH 079/202] outlined --- 04_6_Creating_a_Segwit_Transaction.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index 27e7e25..c3609fd 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -1,5 +1,29 @@ +# 4.6: Creating a SegWit Transaction + +> :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. + +Once upon a time, the Bitcoin heavens shook + +## Understand a SegWit Transaction + +## Create a SegWit Address + ``` $ bitcoin-cli getnewaddress tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 ``` + +## Send a SegWit Transaction + +## Summary: Creating a SegWit Transaction + +[desc] + +> :fire: ***What the power of sending coins with SegWit?*** + +[desc] + +## What's Next? + Advance through "bitcoin-cli" with [Chapter Five: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md). + From 971c1ca100a99abd2c4883b493b0aade80c9988c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 09:34:32 -1000 Subject: [PATCH 080/202] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dd0ed4..a07995a 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,9 @@ _This tutorial assumes that you have some minimal background of how to use the c **Status:** Unwritten. Chapter 14 may expand into multiple chapters. -* 13.0: Setting Up Lightning +(At this point, I'm assuming that Lightning will be integrated into Standup, at which point we just need to tech how to use it.) + +* 13.0: Understanding Lightning * 14.0: Using Lightning > _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/._ From 02b8ea5cdd6711a63fa97ed0f7d4fcea7addac48 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 09:40:47 -1000 Subject: [PATCH 081/202] additional info on Lightning --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a07995a..81b254c 100644 --- a/README.md +++ b/README.md @@ -90,10 +90,15 @@ _This tutorial assumes that you have some minimal background of how to use the c **Status:** Unwritten. Chapter 14 may expand into multiple chapters. -(At this point, I'm assuming that Lightning will be integrated into Standup, at which point we just need to tech how to use it.) +(At this point, I'm assuming that Lightning will be integrated into Standup, at which point we just need to tech how to use it at a pretty basic level.) * 13.0: Understanding Lightning + * 13.1: Verifying Your Lightning Setup + * 13.2: Setting up a Channel + * 13.3: Receiving a Transaction * 14.0: Using Lightning + * 14.1: Sending a Transaction + * 14.X: Closing a Channel > _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/._ From dac45b96e0a441734c8d7c86deafee6aa14a937d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 10:21:30 -1000 Subject: [PATCH 082/202] Added info on SegWit addresses Also linked to 4.6 --- 03_3_Setting_Up_Your_Wallet.md | 40 ++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/03_3_Setting_Up_Your_Wallet.md b/03_3_Setting_Up_Your_Wallet.md index 8e7166d..0082c23 100644 --- a/03_3_Setting_Up_Your_Wallet.md +++ b/03_3_Setting_Up_Your_Wallet.md @@ -6,27 +6,49 @@ You're now ready to start working with Bitcoin. To begin with, you'll need to cr ## 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`. Bitcoin Core 0.16.0 gives p2sh-segwit as default address, this can be changed by `-addresstype`. Otherwise, you can specify the address type between "legacy", "p2sh-segwit", and "bech32". +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`. +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. ``` -$ bitcoin-cli getnewaddress "" legacy +$ bitcoin-cli getnewaddress -addresstype legacy moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B ``` -Note that this address begins with an "m" (or sometimes an "n", "2", or "tb1). This signifies that this is a testnet address. +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. -The "legacy" flag is necessary to generate a traditional address, rather than a p2sh-segwit or bech32 address. The legacy address is currently required from the command line to make sure that signing works correctly. +> :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", "3", or "bc1". 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. 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 P2PKH address?*** A Bitcoin address is also something else: a public key (or more precisely, the 160-bit hash of a public key). For this reason it's called a Pay to PubKey Hash (or P2PKH) address. This public key of your key pair allows you to receive money, while an associated private key lets you spend that money. However, bitcoins may be sent to other sorts of addresses: Pay to Script Hash (P2SH) and Native Segwit (Bech32) addresses feature prominently in the latter part of this tutorial. +> :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! -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 talk about a few other wallet commands that you might want to use in the future. +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. + +### Knowing Your Bitcoin Addresses + +There are three types of Bitcoin addresses that you can create with the `getnewaddress` RPC command. You'll be using a `legacy` (P2PKH) address here, while you'll move over to a SegWit (P2SH-SegWit) or Bech32 address in [§4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md). + +As noted above, the foundation of a Bitcoin address is a public key: someone sends funds to your public key, and then you use your private key to redeem it. Easy? Except putting your public key out there isn't entirely secure. At the moment, if someone has your public key, then they can't retrieve your private key (and thus your funds); that's the basis of cryptography, which uses a trap-door function to ensure that you can only go from private to public key, and not vice-versa. But the problem is that we don't know what the future might bring. Except we do know that cryptography systems eventually get broken by the relentless advance of technology, so it's better not to put raw public keys on the 'net, to future-proof your transactions. + +Classic Bitcoin transactions created P2PKH addresses that added an additional cryptographic step to protect public keys. + +> :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. + +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 + +There are two addresses of this sort: + +> :book: ***What is a P2SH-SegWit (Nested SegWit) address?*** This is the first generation of SegWit. It wraps the SegWit address in a Script hash to ensure backward compatibility. The result creates transactions that are about 25%+ smaller (with corresponding reductions in transaction fees). + +> :book: ***What is a Bech32 (Native SegWit) address?*** This is the second generation of SegWit. It's fully described in [BIP 173](https://en.bitcoin.it/wiki/BIP_0173). It creates transactions that are even smaller but more notably also has some advantages in creating addresses that are less prone to human error and have some implicit error-correction beyond that. It is *not* backward compatible like P2SH-SegWit was, and so some people may not be able to send to it. + +There are other sorts of Bitcoin addresses, such as P2PK (which paid to a bare public key, and is deprecated because of its future insecurity) and P2SH (which pays to a Script Hash, and which is used by the first-generation Nested SegWit addresses; we'll meet it more fully in a few chapters). ## Optional: Sign a Message From ac3fc8ebe3cf5589250d93c954ee475393c1a646 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 10:26:22 -1000 Subject: [PATCH 083/202] added 4.6 reference --- 04_4_Sending_Coins_with_a_Raw_Transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_4_Sending_Coins_with_a_Raw_Transaction.md b/04_4_Sending_Coins_with_a_Raw_Transaction.md index f869fd0..1f9c148 100644 --- a/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -16,7 +16,7 @@ $ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) $ echo $changeaddress mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h ``` -Note that this uses a new function: `getrawchangeaddress`. It's largely the same as `getnewaddress` but is optimized for use as a change address in a raw transaction, so it doesn't do things like make entries in your address book. +Note that this uses a new function: `getrawchangeaddress`. It's largely the same as `getnewaddress` but is optimized for use as a change address in a raw transaction, so it doesn't do things like make entries in your address book. We again selected the `legacy` address, instead of going with the default of `bech32`, simply for consistency. This is a situation where it would have been entirely safe to generate a default Bech32 address, just by using `bitcoin-cli getrawchangeaddress`, because it would being sent and received by you on your Bitcoin Core node which fully supports this. But, hobgoblins; we'll shift this over to Bech32 as well in [§4.6](04_6_Creating_a_Segwit_Transaction.md). You now have an additional address inside your wallet, so that you can receive change from a UTXO! In order to use it, you'll need to create a raw transaction with two outputs. From b17a8011eb22c33f931ca1ce4574fdaefd25b4ef Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 10:29:35 -1000 Subject: [PATCH 084/202] another link to 4.6 discussion --- 04_5_Sending_Coins_with_Automated_Raw_Transactions.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md index c13136f..d834762 100644 --- a/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ b/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -100,7 +100,9 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 ] } ``` -We saw the fee in the more extensive output, before we saved the hex to a variable with JQ, but 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): +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. + +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): ``` $ ~/txfee-calc.sh $rawtxhex3 .000222 From 9335c861a9866e46852d334122b41a29cfaab659 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 10:31:28 -1000 Subject: [PATCH 085/202] Update TODO.md --- TODO.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/TODO.md b/TODO.md index 2bdcda4..8ee18ae 100644 --- a/TODO.md +++ b/TODO.md @@ -23,7 +23,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Edit Chapter 1 **6/19** * Re-edit Chapter 2 **6/19** * Edit & Check Chapter 3 **6/19** - * Edit & Check Chapter 4 **4.1 through 4.4; 4.5 waiting** + * Edit & Check Chapter 4 **6/23** * Double-check fee calculator in 4.2I with a more complex example **6/19** * Integrate older Curl Interlude **6/19** * Edit & Check Chapter 5 @@ -49,8 +49,9 @@ Per @ChristopherA: Add and document the following new concepts: 11. Add SegWit Transactions. The majority of Bitcoin transactions now use this signing methodology, so it needs to be fully explained and incorporated, alongside its newer bech32 addresses. - * Add definitions of Segwit and bech32 addresses to 3.3 - * Do we still have to use "bitcoin-cli getnewaddress "" legacy" on CLI? If not, run back through chapters that use legacy in their examples, starting in 3.3 + * Add definitions of Segwit and bech32 addresses to 3.3 **6/23** + * Do we still have to use "bitcoin-cli getnewaddress "" legacy" on CLI? If not, run back through chapters that use legacy in their examples, starting in 3.3 **Gonna leave it for now. A future version might shift to P2SH-SegWit as default.** + * Integrate discussions of SegWit into early parts of chapter 4. **6/23** * Write chapter 4.6 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). 13. Add Wallet Updates. Some improvements have been made to wallet functionality, including Bitcoin Descriptors, and they should be added to the course. From a750e9ac47a5c991fdd8e31ff703589cdc1f788f Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 23 Jun 2020 22:33:46 +0200 Subject: [PATCH 086/202] Create Client.java --- src/Client.java | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/Client.java diff --git a/src/Client.java b/src/Client.java new file mode 100644 index 0000000..bc8ebe2 --- /dev/null +++ b/src/Client.java @@ -0,0 +1,118 @@ +import java.math.*; +import java.nio.ByteBuffer; +import javax.xml.bind.DatatypeConverter; +import java.util.Hashtable; +import java.util.Enumeration; +import java.math.BigDecimal; +import wf.bitcoin.javabitcoindrpcclient.BitcoinJSONRPCClient; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.SignedRawTransaction; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.AddressInfo; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.RawTransactionSigningOrVerificationError; +import wf.bitcoin.javabitcoindrpcclient.*; +import wf.bitcoin.krotjson.HexCoder; +import java.text.DecimalFormat; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.Unspent; +import wf.bitcoin.javabitcoindrpcclient.BitcoinRawTxBuilder; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.Transaction; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.ExtendedTxInput; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient.TxInput; +import java.util.ListIterator; +import java.net.URL; +import java.net.MalformedURLException; +import java.util.List; +import java.io.*; +import java.util.*; + +public class Client{ + + static BitcoinJSONRPCClient bitcoinClient = null; + static BitcoinRawTxBuilder txb = null; + static String address = ""; + + public boolean connect(){ + String user = "user"; + String password = "password"; + String host = "127.0.0.1"; + String port = "18443"; //regtest +// String host = "192.168.0.22"; //testnet +// String port = "18332"; //testnet + try { + URL url = new URL("http://" + user + ':' + password + "@" + host + ":" + port + "/"); + bitcoinClient = new BitcoinJSONRPCClient(url); + return true; + }catch (MalformedURLException e) { + e.printStackTrace(); + return false; + } + } + + public static void main(String args[]){ + BigDecimal txToAddr2Amount = new BigDecimal("0"); + BigDecimal estimatedFee = BigDecimal.valueOf(0.00000200); + Client rpcClient = new Client(); + bitcoin.connect(); + LinkedList inputList = new LinkedList(); + txb = new BitcoinRawTxBuilder(bitcoinClient); +// String addr1 = bitcoinClient.getNewAddress(); + String addr1 = "bcrt1qs4ylwj2v5v0gq7eqzp9k9vxazdrkexhkghxpyp"; //regtest + AddressInfo addr1Info = bitcoinClient.getAddressInfo(addr1); + System.out.println("Address: " + addr1Info.address()); + System.out.println("HdKeyPath: " + addr1Info.hdKeyPath()); + System.out.println("PubKey: " + addr1Info.pubKey()); + System.out.println("MasterFingerPrint: " + addr1Info.hdMasterFingerprint()); + System.out.println("Balance: " + bitcoinClient.getBalance()); + +// String addr1 = "tb1qrj3dgs6kh2mtr7ulgmlx3pvavqwtw6vxdk468y"; //testnet + System.out.println("Created address addr1: " + addr1); + String addr2 = bitcoinClient.getNewAddress(); + System.out.println("Created address addr2: " + addr2); + List generatedBlocksHashes = bitcoinClient.generateToAddress(110, addr1); + System.out.println("Generated " + generatedBlocksHashes.size() + " blocks for addr1"); + List utxos = bitcoinClient.listUnspent(0, Integer.MAX_VALUE, addr1); + System.out.println("Found " + utxos.size() + " UTXOs (unspent transaction outputs) belonging to addr1"); + /*for(int i =0;i errors = srTx.errors(); + if (errors != null) + { + System.out.println("Found errors when signing"); + + for (RawTransactionSigningOrVerificationError error : errors) + { + System.out.println("Error: " + error); + } + } + + String sentRawTransactionID = bitcoinClient.sendRawTransaction(srTx.hex()); + System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID); + + } +} From 9a98c5d84733be16159ab1d7b5ae710396ee63e8 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 11:24:03 -1000 Subject: [PATCH 087/202] status update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81b254c..f7a6b18 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART ONE: PREPARING FOR BITCOIN -**Status:** Undergoing light editing. Needs to have concepts brought up to 0.20. +**Status:** May need new concepts from 0.20. * [1.0: Introducing Bitcoin](01_0_Introducing_Bitcoin.md) * [2.0: Setting Up a Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) From 4c6a21d1edc7cdf2342cf2ad1c72e52ccdd5cede Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 00:05:36 +0200 Subject: [PATCH 088/202] Update 15_1_Accessing_Bitcoind_with_C.md --- 15_1_Accessing_Bitcoind_with_C.md | 107 +++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 25 deletions(-) diff --git a/15_1_Accessing_Bitcoind_with_C.md b/15_1_Accessing_Bitcoind_with_C.md index c5c532f..bd10a39 100644 --- a/15_1_Accessing_Bitcoind_with_C.md +++ b/15_1_Accessing_Bitcoind_with_C.md @@ -2,18 +2,37 @@ > **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. -[needs new intro] +Interacting with the bitcoind directly and using command-line curl can get simple if you understand how it works, thus in this section we'll show how to use a good package for doing so in C called libbitcoinrpc that provides the functionality to access JSON-RPC bitcoind API. It uses a curl library for accessing the data and it uses the jansson library for encoding and decoding the JSON. ## Set Up libbitcoinrpc 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 a Ubuntu system: ``` $ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev +Suggested packages: + libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev +The following NEW packages will be installed: + libcurl4-openssl-dev libjansson-dev uuid-dev +0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. +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. ``` $ sudo apt-get unzip $ unzip libbitcoinrpc-master.zip +unzip libbitcoinrpc-master.zip +Archive: libbitcoinrpc-master.zip +a2285e8f221185cd0afdcfaf1bc8c78988fce09a + creating: libbitcoinrpc-master/ + inflating: libbitcoinrpc-master/.gitignore + inflating: libbitcoinrpc-master/.travis.yml + inflating: libbitcoinrpc-master/CREDITS + inflating: libbitcoinrpc-master/Changelog.md + inflating: libbitcoinrpc-master/LICENSE + inflating: libbitcoinrpc-master/Makefile + inflating: libbitcoinrpc-master/README.md $ cd libbitcoinrpc-master/ ``` @@ -36,11 +55,55 @@ INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include Then you can compile: ``` -$ make +$ ~/libbitcoinrpc-master$ make + +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ +src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ +-o .lib/libbitcoinrpc.so.0.2 \ +-Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl +ldconfig -v -n .lib +.lib: + libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) +ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so +~/libbitcoinrpc-master$ sudo make install +Installing to +install .lib/libbitcoinrpc.so.0.2 /usr/local/lib +ldconfig -n /usr/local/lib +ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so +install -m 644 src/bitcoinrpc.h /usr/local/include +Installing docs to /usr/share/doc/bitcoinrpc +mkdir -p /usr/share/doc/bitcoinrpc +install -m 644 doc/*.md /usr/share/doc/bitcoinrpc +install -m 644 CREDITS /usr/share/doc/bitcoinrpc +install -m 644 LICENSE /usr/share/doc/bitcoinrpc +install -m 644 Changelog.md /usr/share/doc/bitcoinrpc +Installing man pages +install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 +~/libbitcoinrpc-master$ + ``` If that works, you can install the package: ``` $ sudo make install +Installing to +install .lib/libbitcoinrpc.so.0.2 /usr/local/lib +ldconfig -n /usr/local/lib +ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so +install -m 644 src/bitcoinrpc.h /usr/local/include +Installing docs to /usr/share/doc/bitcoinrpc +mkdir -p /usr/share/doc/bitcoinrpc +install -m 644 doc/*.md /usr/share/doc/bitcoinrpc +install -m 644 CREDITS /usr/share/doc/bitcoinrpc +install -m 644 LICENSE /usr/share/doc/bitcoinrpc +install -m 644 Changelog.md /usr/share/doc/bitcoinrpc +Installing man pages +install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 ``` ## Write Code in C @@ -212,7 +275,7 @@ Successfully connected to server! ``` ## Appendix II: Getting Mining Info -Here's the complete code for the `getmininginfo` command, with organized variable initiatialization, error checking, and variable cleanup. +Here's the complete code for the `getmininginfo` command, with organized variable initiatialization, error checking, and variable cleanup. For this example we use a regtest network and show it's output. ``` file: getmininginfo.c @@ -233,7 +296,7 @@ int main(void) { bitcoinrpc_global_init(); - rpc_client = bitcoinrpc_cl_init_params ("bitcoinrpc", "73bd45ba60ab8f9ff9846b6404769487", "127.0.0.1", 18332); + rpc_client = bitcoinrpc_cl_init_params ("bitcoinrpc", "73bd45ba60ab8f9ff9846b6404769487", "127.0.0.1", 18443); if (rpc_client) { getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); @@ -295,32 +358,26 @@ As usual, you can compile and run as follows: $ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo $ ./getmininginfo Full Response: { - "id": "03406237-cd8f-466d-ac31-86711ea9d1db", "result": { - "blocks": 1147154, - "errors": "Warning: unknown new rules activated (versionbit 28)", - "pooledtx": 0, - "currentblocksize": 0, - "currentblockweight": 0, - "currentblocktx": 0, - "difficulty": 313525.08513550513, - "networkhashps": 3958339463617.417, - "chain": "test" + "blocks": 1100, + "difficulty": 4.6565423739069252e-10, + "networkhashps": 0.01006838108822419, + "pooledtx": 1, + "chain": "regtest", + "warnings": "" }, - "error": null + "error": null, + "id": "d07a55cc-000a-469e-ad7f-c8cef46644da" } Just the Result: { - "blocks": 1147154, - "errors": "Warning: unknown new rules activated (versionbit 28)", - "pooledtx": 0, - "currentblocksize": 0, - "currentblockweight": 0, - "currentblocktx": 0, - "difficulty": 313525.08513550513, - "networkhashps": 3958339463617.417, - "chain": "test" + "blocks": 1100, + "difficulty": 4.6565423739069252e-10, + "networkhashps": 0.01006838108822419, + "pooledtx": 1, + "chain": "regtest", + "warnings": "" } -Block Count: 1147154 +Block Count: 1100 ``` From debe6516a12c2d0f246d189d6e8d8dd4e23cd605 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:13:48 -1000 Subject: [PATCH 089/202] complete first draft --- 04_6_Creating_a_Segwit_Transaction.md | 266 +++++++++++++++++++++++++- 1 file changed, 262 insertions(+), 4 deletions(-) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index c3609fd..19ed4e7 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -2,28 +2,286 @@ > :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. -Once upon a time, the Bitcoin heavens shook +Once upon a time, the Bitcoin heavens shook with the blocksize wars. Users were worried about scaling, fees were skyrocketing. The Bitcoin Core developers were reluctant to simply increase the blocksize, so they arrived upon another solution: SegWit, the Segregated Witness. Segregated Witness is a fancy way of saying "Separated Signature". It creates new sorts of addresses that remove signatures to the end of the transaction. By combining this with increased block sizes that only are visible to upgraded nodes, SegWit resolved the scaling problems for Bitcoin at the time (and also resolved a nasty malleability bug that made improved scaling with layer-2 protocols like Lightning unfeasible). + +The catch? SegWit uses different addresses, some of which are compatible with older nodes, of some of which are not. + +> :warning: **VERSION WARNING:** SegWit was introduced in BitCoin 0.16.0 with what was described at the time as "full support". With that said, there were some flaws in its integration with `bitcoin-cli` which prevented signing from working correctly on new P2SH-SegWit addresses. The non-backward-compatible Bech32 address was also introduced in Bitcoin 0.16.0 and made the default addresstype in Bitcoin 0.19.0. All of this functionality should now fully work with regard to `bitcoin-cli` functions (and thus this tutorial). The catch comes in interacting with the wider world. Everyone should be able to send to a P2SH-SegWit address, because it was purposefully built to support backward compatibility by wrapping the SegWit functionality in a Bitcoin Script. The same isn't true for Bech32 addresses: if someone tells you that they're unable to send to your Bech32 address, this is why, and you need to generate a `legacy` or P2SH-SegWit address for their usage. (Many sites, particularly exchanges, can also not generate or receive on SegWit addresses, particularly Bech32 addresses, but that's a whole different issue and doesn't affect your usage of them). ## 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 sizde block, up to the new 4M limit). + +So that's the what and how og 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 +You create a SegWit address the same way as any other address, with the `getnewaddress` and the `getrawchangeaddress` commands. + +If you need to create an address for someone who can't send to the newer Bech32 addresses, then use the `p2sh-segwit` addresstype: +``` +$ bitcoin-cli getnewaddress -addresstype p2sh-segwit +2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN +``` +Seeing an address with a "2" prefix means that you did it right. + +> :link: **TESTNET vs MAINNET:** "3" for Mainnet. + +However, if the person you're interacting with has a fully mature client, they'll be able to send to a Bech32 address, which you create using the commands in the default way: ``` $ bitcoin-cli getnewaddress tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 ``` +As we've already seen, change addresses generated from within `bitcoin-cli` interact fine with Bech32 addresses, so there's no point in using the `legacy` flag there either: +``` +$ bitcoin-cli getrawchangeaddress +tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff +``` + +There are 2 different Segwit address formats. They are P2SH (starting with a "3") and bech32 (starting "bc1") +P2SH can be sent to by people using older Bitcoin software with no Segwit support. This supports backwards compatibility +People sending from newer Bitcoin software that has Segwit and bech32 can send to the new address type that starts "bc1" +People sending from older Bitcoin software that has no Segwit probably cannot send to the new address type that starts "bc1" + +So, if people send you BTC from old software, give them the Segwit addresses that start with "3". If people send you BTC using new Segwit Bitcoin software, give them the Segwit addresses that start with "bc1". + +``` +$ bitcoin-cli getnewaddress +tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 +``` +And Bitcoin-cli doesn't care. You can run a command like `listaddressgroupings` and it will freely mix addresses of the different types: +``` +$ bitcoin-cli listaddressgroupings +[ + [ + [ + "mfsiRhxbQxcD7HLS4PiAim99oeGyb9QY7m", + 0.01000000, + "" + ] + ], + [ + [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + 0.00000000, + "" + ], + [ + "tb1q6dak4e9fz77vsulk89t5z92l2e0zm37yvre4gt", + 0.00000000 + ] + ], + [ + [ + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + 0.00022000, + "" + ] + ], + [ + [ + "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + 0.00000000 + ], + [ + "mqjrdY5raxKzXQf5t2VvVvzhvFAgersu9B", + 0.00000000 + ], + [ + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + 0.00000000, + "" + ], + [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + 0.00007800 + ] + ], + [ + [ + "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + 0.01000000, + "" + ] + ], + [ + [ + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + 0.01000000, + "" + ] + ] +] +``` + ## Send a SegWit Transaction +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. (And this is one of the advantages of using the command line and the RPC interface, as suggested in this tutorial: because experts have already done the hard work for you, including things 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: +``` +$ bitcoin-cli sendtoaddress address=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 +854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 +``` +If you look at your transaction, you can see use of the Bech32 address: +``` +$ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true +{ + "amount": -0.00500000, + "fee": -0.00036600, + "confirmations": 0, + "trusted": true, + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "walletconflicts": [ + ], + "time": 1592948795, + "timereceived": 1592948795, + "bip125-replaceable": "no", + "details": [ + { + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", + "category": "send", + "amount": -0.00500000, + "vout": 1, + "fee": -0.00036600, + "abandoned": false + } + ], + "hex": "0200000002114d5a4c3b847bc796b2dc166ca7120607b874aa6904d4a43dd5f9e0ea79d4ba010000006a47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042dfeffffffa71321e81ef039af490251379143f7247ad91613c26c8f3e3404184218361733000000006a47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7efeffffff026854160000000000160014d591091b8074a2375ed9985a9c4b18efecfd416520a1070000000000160014751e76e8199196d454941c45d1b3a323f1433bd6c60e1b00", + "decoded": { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "hash": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "version": 2, + "size": 366, + "vsize": 366, + "weight": 1464, + "locktime": 1773254, + "vin": [ + { + "txid": "bad479eae0f9d53da4d40469aa74b8070612a76c16dcb296c77b843b4c5a4d11", + "vout": 1, + "scriptSig": { + "asm": "304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7[ALL] 03ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d", + "hex": "47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d" + }, + "sequence": 4294967294 + }, + { + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "vout": 0, + "scriptSig": { + "asm": "304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a316[ALL] 0339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e", + "hex": "47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01463400, + "n": 0, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + ] + } + }, + { + "value": 0.00500000, + "n": 1, + "scriptPubKey": { + "asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6", + "hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx" + ] + } + } + ] + } +} +``` +In fact, both of the `vouts` use Bech32 addresses. + +But when we backtrack our `vin`, we discover that came from a legacy address. Because it doesn't matter: +``` +$ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" +{ + "amount": 0.01000000, + "confirmations": 43, + "blockhash": "00000000000000e2365d2f814d1774b063d9a04356f482010cdfdd537b1a24bb", + "blockheight": 1773212, + "blockindex": 103, + "blocktime": 1592937103, + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "walletconflicts": [ + ], + "time": 1592936845, + "timereceived": 1592936845, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 0 + } + ], + "hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00" +} +``` +You can similarly fund a transaction with a Bech32 address with no difference to the techniques you've learned so far: +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress) +$ echo $changeaddress +tb1q4xje3mx9xn7f8khv7p69ekfn0q72kfs8x3ay4j +$ bitcoin-cli listunspent +[ +... + { + "txid": "003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452", + "vout": 0, + "address": "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + "label": "", + "scriptPubKey": "0014a226e1dfd08537b02de04f667a49bd46f9b9f578", + "amount": 0.01000000, + "confirmations": 5, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp", + "safe": true + } +] +$ recipient=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +$ echo $utxo_txid $utxo_vout +003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0 +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +standup@btctest20:~$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c +``` +It all works exactly the same as other sorts of transactions! + ## Summary: Creating a SegWit Transaction -[desc] +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?*** -[desc] +> _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 hard to make mistakes when transcribing — and that's pretty important, given that user error is one of the most likely ways to lose your Bitcoins. + +> _The Disadvantages._ SegWit transactions may not be supported by obsolete Bitcoin software. In particular, people may not be able to send to your Bech32 address. ## What's Next? Advance through "bitcoin-cli" with [Chapter Five: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md). - From 87545f4d2cb0172bc6ae847393b0007454caacf4 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:16:01 -1000 Subject: [PATCH 090/202] Whoop! Left a few notes and references. Plus added fixes. --- 04_6_Creating_a_Segwit_Transaction.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index 19ed4e7..8b26618 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -32,25 +32,17 @@ However, if the person you're interacting with has a fully mature client, they'l $ bitcoin-cli getnewaddress tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 ``` - As we've already seen, change addresses generated from within `bitcoin-cli` interact fine with Bech32 addresses, so there's no point in using the `legacy` flag there either: ``` $ bitcoin-cli getrawchangeaddress tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff ``` -There are 2 different Segwit address formats. They are P2SH (starting with a "3") and bech32 (starting "bc1") -P2SH can be sent to by people using older Bitcoin software with no Segwit support. This supports backwards compatibility -People sending from newer Bitcoin software that has Segwit and bech32 can send to the new address type that starts "bc1" -People sending from older Bitcoin software that has no Segwit probably cannot send to the new address type that starts "bc1" +Again note the unique "tb1" prefix denoted Bech32. -So, if people send you BTC from old software, give them the Segwit addresses that start with "3". If people send you BTC using new Segwit Bitcoin software, give them the Segwit addresses that start with "bc1". +> :link: **TESTNET vs MAINNET:** "bc1" for mainnet. -``` -$ bitcoin-cli getnewaddress -tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 -``` -And Bitcoin-cli doesn't care. You can run a command like `listaddressgroupings` and it will freely mix addresses of the different types: +Bitcoin-cli doesn't care which address type you're using. You can run a command like `listaddressgroupings` and it will freely mix addresses of the different types: ``` $ bitcoin-cli listaddressgroupings [ @@ -115,7 +107,7 @@ $ bitcoin-cli listaddressgroupings ] ``` -## Send a SegWit Transaction +## 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. (And this is one of the advantages of using the command line and the RPC interface, as suggested in this tutorial: because experts have already done the hard work for you, including things how to send to both legacy and Bech32 addresses. You just get to use that functionality to your own advantage.) @@ -238,6 +230,9 @@ $ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f743 "hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00" } ``` + +## Send a SegWit Transaction The Hard Way + You can similarly fund a transaction with a Bech32 address with no difference to the techniques you've learned so far: ``` $ changeaddress=$(bitcoin-cli getrawchangeaddress) From f1cdf7f00e16dfc650bb2136fd4f3a87d8c1e13c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:17:14 -1000 Subject: [PATCH 091/202] updated for SegWit section --- 04_0_Sending_Bitcoin_Transactions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/04_0_Sending_Bitcoin_Transactions.md b/04_0_Sending_Bitcoin_Transactions.md index 2b18a4d..b3b7554 100644 --- a/04_0_Sending_Bitcoin_Transactions.md +++ b/04_0_Sending_Bitcoin_Transactions.md @@ -13,6 +13,7 @@ After working through this chapter, a developer will be able to: Supporting objectives include the ability to: * Understand Transactions & Transaction Fees + * Understand Legacy & SegWit Transactions * Use Basic Methods to Send Money * Use Auto Fee Calculation Methods to Send Money * Understand the Dangers of Raw Transactions @@ -25,3 +26,4 @@ Supporting objectives include the ability to: * [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) * [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) From e48133d4953ed4d64c08089082af558b56d11321 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:30:01 -1000 Subject: [PATCH 092/202] more names for SegWit addresses --- 03_3_Setting_Up_Your_Wallet.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/03_3_Setting_Up_Your_Wallet.md b/03_3_Setting_Up_Your_Wallet.md index 0082c23..d79938f 100644 --- a/03_3_Setting_Up_Your_Wallet.md +++ b/03_3_Setting_Up_Your_Wallet.md @@ -44,9 +44,9 @@ SegWit simply means "segregated witness" and it's a way of separating the transa There are two addresses of this sort: -> :book: ***What is a P2SH-SegWit (Nested SegWit) address?*** This is the first generation of SegWit. It wraps the SegWit address in a Script hash to ensure backward compatibility. The result creates transactions that are about 25%+ smaller (with corresponding reductions in transaction fees). +> :book: ***What is a P2SH-SegWit (aka Nested SegWit, aka P2WSH) address?*** This is the first generation of SegWit. It wraps the SegWit address in a Script hash to ensure backward compatibility. The result creates transactions that are about 25%+ smaller (with corresponding reductions in transaction fees). -> :book: ***What is a Bech32 (Native SegWit) address?*** This is the second generation of SegWit. It's fully described in [BIP 173](https://en.bitcoin.it/wiki/BIP_0173). It creates transactions that are even smaller but more notably also has some advantages in creating addresses that are less prone to human error and have some implicit error-correction beyond that. It is *not* backward compatible like P2SH-SegWit was, and so some people may not be able to send to it. +> :book: ***What is a Bech32 (aka Native SegWit, aka P2WPKH) address?*** This is the second generation of SegWit. It's fully described in [BIP 173](https://en.bitcoin.it/wiki/BIP_0173). It creates transactions that are even smaller but more notably also has some advantages in creating addresses that are less prone to human error and have some implicit error-correction beyond that. It is *not* backward compatible like P2SH-SegWit was, and so some people may not be able to send to it. There are other sorts of Bitcoin addresses, such as P2PK (which paid to a bare public key, and is deprecated because of its future insecurity) and P2SH (which pays to a Script Hash, and which is used by the first-generation Nested SegWit addresses; we'll meet it more fully in a few chapters). From e0d5053b9c991c1e553d00aeac25646f68350a31 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:51:38 -1000 Subject: [PATCH 093/202] edited new chapter --- 04_6_Creating_a_Segwit_Transaction.md | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index 8b26618..7eb83d7 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -2,17 +2,19 @@ > :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. -Once upon a time, the Bitcoin heavens shook with the blocksize wars. Users were worried about scaling, fees were skyrocketing. The Bitcoin Core developers were reluctant to simply increase the blocksize, so they arrived upon another solution: SegWit, the Segregated Witness. Segregated Witness is a fancy way of saying "Separated Signature". It creates new sorts of addresses that remove signatures to the end of the transaction. By combining this with increased block sizes that only are visible to upgraded nodes, SegWit resolved the scaling problems for Bitcoin at the time (and also resolved a nasty malleability bug that made improved scaling with layer-2 protocols like Lightning unfeasible). +Once upon a time, the Bitcoin heavens shook with the blocksize wars. Fees were skyrocketing, and users were worried about scaling. The Bitcoin Core developers were reluctant to simply increase the blocksize, but they came upon a compromise: SegWit, the Segregated Witness. Segregated Witness is a fancy way of saying "Separated Signature". It creates new sorts of transactions that remove signatures to the end of the transaction. By combining this with increased block sizes that only are visible to upgraded nodes, SegWit resolved the scaling problems for Bitcoin at the time (and also resolved a nasty malleability bug that had previously made even better scaling with layer-2 protocols like Lightning impractical). -The catch? SegWit uses different addresses, some of which are compatible with older nodes, of some of which are not. +The catch? SegWit uses different addresses, some of which are compatible with older nodes, and some of which are not. -> :warning: **VERSION WARNING:** SegWit was introduced in BitCoin 0.16.0 with what was described at the time as "full support". With that said, there were some flaws in its integration with `bitcoin-cli` which prevented signing from working correctly on new P2SH-SegWit addresses. The non-backward-compatible Bech32 address was also introduced in Bitcoin 0.16.0 and made the default addresstype in Bitcoin 0.19.0. All of this functionality should now fully work with regard to `bitcoin-cli` functions (and thus this tutorial). The catch comes in interacting with the wider world. Everyone should be able to send to a P2SH-SegWit address, because it was purposefully built to support backward compatibility by wrapping the SegWit functionality in a Bitcoin Script. The same isn't true for Bech32 addresses: if someone tells you that they're unable to send to your Bech32 address, this is why, and you need to generate a `legacy` or P2SH-SegWit address for their usage. (Many sites, particularly exchanges, can also not generate or receive on SegWit addresses, particularly Bech32 addresses, but that's a whole different issue and doesn't affect your usage of them). +> :warning: **VERSION WARNING:** SegWit was introduced in BitCoin 0.16.0 with what was described at the time as "full support". With that said, there were some flaws in its integration with `bitcoin-cli` at the time which prevented signing from working correctly on new P2SH-SegWit addresses. The non-backward-compatible Bech32 address was also introduced in Bitcoin 0.16.0 and was made the default addresstype in Bitcoin 0.19.0. All of this functionality should now fully work with regard to `bitcoin-cli` functions (and thus this tutorial). + +> The catch comes in interacting with the wider world. Everyone should be able to send to a P2SH-SegWit address because it was purposefully built to support backward compatibility by wrapping the SegWit functionality in a Bitcoin Script. The same isn't true for Bech32 addresses: if someone tells you that they're unable to send to your Bech32 address, this is why, and you need to generate a `legacy` or P2SH-SegWit address for their usage. (Many sites, particularly exchanges, can also not generate or receive on SegWit addresses, particularly Bech32 addresses, but that's a whole different issue and doesn't affect your usage of them.) ## 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 sizde 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 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). -So that's the what and how og 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 @@ -38,7 +40,7 @@ $ bitcoin-cli getrawchangeaddress tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff ``` -Again note the unique "tb1" prefix denoted Bech32. +Here, note that the unique "tb1" prefix denoted Bech32. > :link: **TESTNET vs MAINNET:** "bc1" for mainnet. @@ -109,14 +111,14 @@ $ 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. (And this is one of the advantages of using the command line and the RPC interface, as suggested in this tutorial: because experts have already done the hard work for you, including things 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 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.) Here's an example of sending to a SegWit address, the easy way: ``` -$ bitcoin-cli sendtoaddress address=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 +$ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 ``` -If you look at your transaction, you can see use of the Bech32 address: +If you look at your transaction, you can see the use of the Bech32 address: ``` $ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true { @@ -200,7 +202,7 @@ $ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c10 } } ``` -In fact, both of the `vouts` use Bech32 addresses. +In fact, both of the `vouts` use Bech32 addresses: your recipient and the automatically generated change address. But when we backtrack our `vin`, we discover that came from a legacy address. Because it doesn't matter: ``` @@ -233,7 +235,7 @@ $ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f743 ## Send a SegWit Transaction The Hard Way -You can similarly fund a transaction with a Bech32 address with no difference to the techniques you've learned so far: +You can similarly fund a transaction with a Bech32 address with no difference to the techniques you've learned so far. Here's an exactly of doing so with a complete raw transaction: ``` $ changeaddress=$(bitcoin-cli getrawchangeaddress) $ echo $changeaddress @@ -262,20 +264,20 @@ $ echo $utxo_txid $utxo_vout 003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0 $ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''') $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') -standup@btctest20:~$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c ``` It all works exactly the same as other sorts of transactions! ## Summary: Creating a SegWit Transaction -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. +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?*** -> _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 hard to make mistakes when transcribing — and that's pretty important, given that user error is one of the most likely ways to lose your Bitcoins. +> _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. -> _The Disadvantages._ SegWit transactions may not be supported by obsolete Bitcoin software. In particular, people may not be able to send to your Bech32 address. +> _The Disadvantages._ SegWit addresses may not be supported by obsolete Bitcoin software. In particular, people may not be able to send to your Bech32 address. ## What's Next? From e05e5aa50556ca650798fabe6ceefbdde2f4cd26 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:52:32 -1000 Subject: [PATCH 094/202] checked off SegWit --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 8ee18ae..23c0fe5 100644 --- a/TODO.md +++ b/TODO.md @@ -48,11 +48,11 @@ Per @ChristopherA: Add and document the following new concepts: -11. Add SegWit Transactions. The majority of Bitcoin transactions now use this signing methodology, so it needs to be fully explained and incorporated, alongside its newer bech32 addresses. +11. Add SegWit Transactions. The majority of Bitcoin transactions now use this signing methodology, so it needs to be fully explained and incorporated, alongside its newer bech32 addresses. **6/23** * Add definitions of Segwit and bech32 addresses to 3.3 **6/23** * Do we still have to use "bitcoin-cli getnewaddress "" legacy" on CLI? If not, run back through chapters that use legacy in their examples, starting in 3.3 **Gonna leave it for now. A future version might shift to P2SH-SegWit as default.** * Integrate discussions of SegWit into early parts of chapter 4. **6/23** - * Write chapter 4.6 + * Write chapter 4.6 **6/23** 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). 13. Add Wallet Updates. Some improvements have been made to wallet functionality, including Bitcoin Descriptors, and they should be added to the course. 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). From 22a39649089038bed92deb9341d07e1295eec7d7 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:55:02 -1000 Subject: [PATCH 095/202] segwit is integrated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7a6b18..b5d5dec 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [4.4: Sending Coins with Raw Transactions](04_4_Sending_Coins_with_a_Raw_Transaction.md) * [Interlude: Using Curl](04_4__Interlude_Using_Curl.md) * [4.5: Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) - * [4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md) — Awaiting Better Integration of Segwit into CLI + * [4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md) * [5.0: Controlling Bitcoin Transactions](05_0_Controlling_Bitcoin_Transactions.md) * [5.1 Watching for Stuck Transactions](05_1_Watching_for_Stuck_Transactions.md) * [5.2: Resending a Transaction with RBF](05_2_Resending_a_Transaction_with_RBF.md) From 56b530a8dfedc21761e5b84336ac9e78da51a7fb Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 12:59:14 -1000 Subject: [PATCH 096/202] removed extra $ --- 04_4_Sending_Coins_with_a_Raw_Transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_4_Sending_Coins_with_a_Raw_Transaction.md b/04_4_Sending_Coins_with_a_Raw_Transaction.md index 1f9c148..207f6c1 100644 --- a/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -100,7 +100,7 @@ Writing the actual raw transaction is surprisingly simple. All you need to do is Here's the example. Note the multiple inputs after the `inputs` arg and the multiple outputs after the `outputs` arg. ``` -$ $ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') +$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') ``` We were _very_ careful figuring out our money math. These two UTXOs contain 5.85 BTC. After sending 0.009 BTC, we'll have .00099999 BTC left. We chose .00009999 BTC the transaction fee. To accommodate that fee, we set our change to .0009 BTC. If we'd messed up our math and instead set our change to .00009 BTC, that additional BTC would be lost to the miners! If we'd forgot to make change at all, then the whole excess would have disappeared. So, again, _be careful_. From 2f191c74db41d6054826d6b31219582670629d29 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 13:03:42 -1000 Subject: [PATCH 097/202] redid single example --- 05_1_Watching_for_Stuck_Transactions.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/05_1_Watching_for_Stuck_Transactions.md b/05_1_Watching_for_Stuck_Transactions.md index 4c19020..aa23a9c 100644 --- a/05_1_Watching_for_Stuck_Transactions.md +++ b/05_1_Watching_for_Stuck_Transactions.md @@ -10,35 +10,33 @@ You should _always_ watch to ensure that your transactions go out. `bitcoin-cli The following shows a transaction that has not been put into a block. You can tell this because it has no confirmations. ``` -$ bitcoin-cli -named gettransaction txid=0f618e38efe887028a5dd04d0e12241431978b4de32f70308c13a114d7cfcbd2 +$ bitcoin-cli -named gettransaction txid=fa2ddf84a4a632586d435e10880a2921db6310dfbd6f0f8f583aa0feacb74c8e { - "amount": -0.84927000, - "fee": -0.00000400, + "amount": -0.00020000, + "fee": -0.00001000, "confirmations": 0, "trusted": true, - "txid": "0f618e38efe887028a5dd04d0e12241431978b4de32f70308c13a114d7cfcbd2", + "txid": "fa2ddf84a4a632586d435e10880a2921db6310dfbd6f0f8f583aa0feacb74c8e", "walletconflicts": [ ], - "time": 1491588722, - "timereceived": 1491588722, + "time": 1592953220, + "timereceived": 1592953220, "bip125-replaceable": "no", "details": [ { - "account": "", - "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", "category": "send", - "amount": -0.84927000, + "amount": -0.00020000, "vout": 0, - "fee": -0.00000400, + "fee": -0.00001000, "abandoned": false } ], - "hex": "0200000001c6cb05c5212bb7ec14add72883a17f0a68aa399354bc2f7cf02df6e7d68a6937000000006a47304402203f21d769cbf3cf1626ef09bb35d0d8e88efe9f14d097f4b493628e96b2e1c90b0220162ff60701525e70942f5090dc48ec2b2f3b87cd40185351ab316991567f61c50121029045eaa55d283526c723e6d5495d9b3f077b545563f86465aafcd9bfdd50359effffffff0118e20f05000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" -} + "hex": "02000000014cda1f42a1bd39d8d0ff5958a804bc2bc548b71d7ceadbde53ea15aeaf1e2691000000006a473044022016a7a9f045a0f6a52129f48adb7da35c2f54a0741d6614e9d55b8a3bc3e1490a0220391e9085a3697bc790e94bb924d5310e16f23489d9c600864a32674e871f523c01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff02204e000000000000160014751e76e8199196d454941c45d1b3a323f1433bd6e8030000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919600000000" ``` A transaction can be considered stuck if it stays in this state for an extended amount of time. Not too many years ago, you could be sure that every transaction would go out _eventually_. But, that's no longer the case due to the increased usage of Bitcoin. Now, if a transaction is stuck too long, it will drop out of the mempool and then be lost from the Bitcoin network. -_What is mempool?_ Mempool (or Memory Pool) is a pool of all unconfirmed transactions at a bitcoin node. These are the transactions that a node has received from the p2p network which are not yet included in a block. Each bitcoin node can have a slightly different set of transactions in its mempool: different transactions might have propogated to a specific node. This depends on when the node was last started and also its limits on how much it's willing to store. When a miner makes a block, he uses transactions from his mempool. Then, when a block is verified, all the miners remove the transactions it contains from their pools. As of Bitcoin 0.12, unconfirmed transactions can also expire from mempools if they're old enough, typically, 72 hours, and as of version 0.14.0 eviction time was increased to 2 weeks. Mining pools might have their own mempool-management mechanisms. +> :book: _What is mempool?_ Mempool (or Memory Pool) is a pool of all unconfirmed transactions at a bitcoin node. These are the transactions that a node has received from the p2p network which are not yet included in a block. Each bitcoin node can have a slightly different set of transactions in its mempool: different transactions might have propogated to a specific node. This depends on when the node was last started and also its limits on how much it's willing to store. When a miner makes a block, he uses transactions from his mempool. Then, when a block is verified, all the miners remove the transactions it contains from their pools. As of Bitcoin 0.12, unconfirmed transactions can also expire from mempools if they're old enough, typically, 72 hours, and as of version 0.14.0 eviction time was increased to 2 weeks. Mining pools might have their own mempool-management mechanisms. This list of all [unconfirmed transactions](https://blockchain.info/unconfirmed-transactions) might not match any individual machine's mempool, but it should (mostly) be a superset of them. From 381bd4bd2361017da019325faf15587d6b7cfe28 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 13:04:08 -1000 Subject: [PATCH 098/202] reformatted :book: for new standard --- 05_1_Watching_for_Stuck_Transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_1_Watching_for_Stuck_Transactions.md b/05_1_Watching_for_Stuck_Transactions.md index aa23a9c..4def26c 100644 --- a/05_1_Watching_for_Stuck_Transactions.md +++ b/05_1_Watching_for_Stuck_Transactions.md @@ -36,7 +36,7 @@ $ bitcoin-cli -named gettransaction txid=fa2ddf84a4a632586d435e10880a2921db6310d ``` A transaction can be considered stuck if it stays in this state for an extended amount of time. Not too many years ago, you could be sure that every transaction would go out _eventually_. But, that's no longer the case due to the increased usage of Bitcoin. Now, if a transaction is stuck too long, it will drop out of the mempool and then be lost from the Bitcoin network. -> :book: _What is mempool?_ Mempool (or Memory Pool) is a pool of all unconfirmed transactions at a bitcoin node. These are the transactions that a node has received from the p2p network which are not yet included in a block. Each bitcoin node can have a slightly different set of transactions in its mempool: different transactions might have propogated to a specific node. This depends on when the node was last started and also its limits on how much it's willing to store. When a miner makes a block, he uses transactions from his mempool. Then, when a block is verified, all the miners remove the transactions it contains from their pools. As of Bitcoin 0.12, unconfirmed transactions can also expire from mempools if they're old enough, typically, 72 hours, and as of version 0.14.0 eviction time was increased to 2 weeks. Mining pools might have their own mempool-management mechanisms. +> :book: ***What is mempool?*** Mempool (or Memory Pool) is a pool of all unconfirmed transactions at a bitcoin node. These are the transactions that a node has received from the p2p network which are not yet included in a block. Each bitcoin node can have a slightly different set of transactions in its mempool: different transactions might have propogated to a specific node. This depends on when the node was last started and also its limits on how much it's willing to store. When a miner makes a block, he uses transactions from his mempool. Then, when a block is verified, all the miners remove the transactions it contains from their pools. As of Bitcoin 0.12, unconfirmed transactions can also expire from mempools if they're old enough, typically, 72 hours, and as of version 0.14.0 eviction time was increased to 2 weeks. Mining pools might have their own mempool-management mechanisms. This list of all [unconfirmed transactions](https://blockchain.info/unconfirmed-transactions) might not match any individual machine's mempool, but it should (mostly) be a superset of them. From 668c284d3c544cc3653efaacdb885d556f0f7ee1 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 13:47:55 -1000 Subject: [PATCH 099/202] updating for 0.20 --- 05_2_Resending_a_Transaction_with_RBF.md | 179 ++++++++--------------- 1 file changed, 62 insertions(+), 117 deletions(-) diff --git a/05_2_Resending_a_Transaction_with_RBF.md b/05_2_Resending_a_Transaction_with_RBF.md index cec62ab..8c2a701 100644 --- a/05_2_Resending_a_Transaction_with_RBF.md +++ b/05_2_Resending_a_Transaction_with_RBF.md @@ -4,7 +4,7 @@ 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. -> :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. +> :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. ## Opt-In for RBF @@ -12,45 +12,37 @@ RBF is an opt-in Bitcoin feature. Transactions are only eligible for using RBF i This is accomplished simply by adding a `sequence` variable to your UTXO inputs: ``` -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.1, "'$changeaddress'": 0.9 }''') +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.00007658, "'$changeaddress'": 0.00000001 }''') ``` You should of course sign and send your transaction as usual: ``` $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') -$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx -7218b78ad4853eb957b610033b8e1ef48b01d948e0ec5dbf79f12caebc2b17e2 +standup@btctest20:~$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 ``` Now, when you look at your transaction, you should see something new: the `bip125-replaceable` line, which has always been marked `no` before, is now marked `yes`: ``` -$ bitcoin-cli -named gettransaction txid=7218b78ad4853eb957b610033b8e1ef48b01d948e0ec5dbf79f12caebc2b17e2 +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 + { - "amount": -0.10000000, - "fee": 0.00000000, + "amount": 0.00000000, + "fee": -0.00000141, "confirmations": 0, "trusted": true, - "txid": "7218b78ad4853eb957b610033b8e1ef48b01d948e0ec5dbf79f12caebc2b17e2", + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", "walletconflicts": [ ], - "time": 1491603320, - "timereceived": 1491603320, + "time": 1592954399, + "timereceived": 1592954399, "bip125-replaceable": "yes", "details": [ - { - "account": "", - "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", - "category": "send", - "amount": -0.10000000, - "vout": 0, - "fee": 0.00000000, - "abandoned": false - } ], - "hex": "02000000014e843e22cb8ee522fbf4d8a0967a733685d2ad92697e63f52ce41bec8f7c8ac0010000006b483045022100834731cd64efcc078d6c3e59cf0963599ffbc44722b7851b0404bb68e4a1fec70220759a0887ea791592c8119bbe61842eb3850a20cdf8433b4ba00d4ead752facfe012103456575f59a127a4c3e79c23f185899fa0a9ccd40162d05617fb112fa31bd14e5010000000280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac804a5d05000000001976a914c101d8c34de7b8d83b3f8d75416ffaea871d664988ac00000000" + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" } ``` The `bip125-replaceable` flag will stay `yes` until the transaction receives confirmations. At that point, it is no longer replacable. -_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. +> :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. > :information_source: **NOTE — SEQUENCE:** This is the first use of the `nSequence` value in Bitcoin. You can set it between 1 and 0xffffffff-2 (4294967293) and enable RBF, but if you're not careful you can run up against the parallel use of `nSequence` for relative timelocks. We suggest always setting it to "1", which is what Bitcoin Core does, but the other option is to set it to a value between 0xf0000000 (4026531840) and 0xffffffff-2 (4294967293). Setting it to "1" effectively makes relative timelocks irrelevent and setting it to 0xf0000000 or higher deactivates them. This is all explained further in [§9.3: Using CSV in Scripts](09_3_Using_CSV_in_Scripts.md). For now, just choose one of the non-conflicting values for `nSequence`. @@ -58,56 +50,6 @@ _Should I trust transactions with no confirmations?_ No, never. This was true be If you prefer, you can _always_ opt in for RBF. Do so by running your `bitcoind` with the `-walletrbf` command. Once you've done this (and restarted your `bitcoind`), then all UTXOs should have a lower sequence number and the transaction should be marked as `bip125-replaceable`. -Note the following example generated by `bitcoind`, where the UTXO indeed uses a sequence number of "1": -``` -{ - "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", - "hash": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", - "size": 226, - "vsize": 226, - "version": 2, - "locktime": 0, - "vin": [ - { - "txid": "4075dbf84303c01adcb0b36cd2c164e2b447192c2d9fbf5fde3b99d0ac7e64b6", - "vout": 1, - "scriptSig": { - "asm": "3045022100b3a0d66abe3429f81a6dc397369d6ac9cb025a2243b68649d95665967fe4365b022038cf037aaab9368268e97203494d1b542e83101e6aaaf97957daf70dee6ee0af[ALL] 022615f4b6417b991530df4bc8c8ee10b8925c741773fead7a5edd89337caeba53", - "hex": "483045022100b3a0d66abe3429f81a6dc397369d6ac9cb025a2243b68649d95665967fe4365b022038cf037aaab9368268e97203494d1b542e83101e6aaaf97957daf70dee6ee0af0121022615f4b6417b991530df4bc8c8ee10b8925c741773fead7a5edd89337caeba53" - }, - "sequence": 1 - } - ], - "vout": [ - { - "value": 0.10000000, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" - ] - } - }, - { - "value": 0.90000000, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 20219e4f3c6bc0f6524d538009e980091b3613e8 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH" - ] - } - } - ] -} -``` > :warning: **VERSION WARNING:** The walletrbf flag require Bitcoin Core v.0.14.0. ## Understand How RBF Works @@ -123,13 +65,13 @@ This means that the sequence number must be set to less than 0xffffffff-1. (4294 > 4. The replacement transaction must pay for its own bandwidth in addition to the amount paid by the original transactions at or above the rate set by the node's minimum relay fee setting. For example, if the minimum relay fee is 1 satoshi/byte and the replacement transaction is 500 bytes total, then the replacement must pay a fee at least 500 satoshis higher than the sum of the originals. > 5. The number of original transactions to be replaced and their descendant transactions which will be evicted from the mempool must not exceed a total of 100 transactions. -_What is a BIP?_ A BIP is a Bitcoin Improvement Proposal. It's an in-depth suggestion for a change to the Bitcoin Core code. Often, when a BIP has been sufficiently discussed and updated, it will become an actual part of the Bitcoin Core code. For example, BIP 125 was implemented in Bitcoin Core 0.12.0. +> :book: ***What is a BIP?*** A BIP is a Bitcoin Improvement Proposal. It's an in-depth suggestion for a change to the Bitcoin Core code. Often, when a BIP has been sufficiently discussed and updated, it will become an actual part of the Bitcoin Core code. For example, BIP 125 was implemented in Bitcoin Core 0.12.0. The other thing to understand about RBF is that in order to use it, you must double-spend, reusing one or more the same UTXOs. Just sending another transaction with a different UTXO to the same recipient won't do the trick (and will likely result in your losing money). Instead, you must purposefully create a conflict, where the same UTXO is used in two different transactions. Faced with this conflict, the miners will know to use the one with the higher fee, and they'll be incentivized to do so by that higher fee. -_What is a double-spend?_ A double-spend occurs when someone sends the same electronic funds to two different people (or, to the same person twice, in two different transactions). This is a central problem for any e-cash system. It's solved in Bitcoin by the immutable ledger: once a transaction is sufficiently confirmed, no miners will verify transactions that reuse the same UTXO. However, it's possible to double-spend _before_ a transaction has been confirmed — which is why you always want one or more confirmations before you finalize a transaction. In the case of RBF, you purposefully double-spend because an initial transaction has stalled, and the miners accept your double-spend if you meet the specific criteria laid out by BIP 125. +> :book: ***What is a double-spend?*** A double-spend occurs when someone sends the same electronic funds to two different people (or, to the same person twice, in two different transactions). This is a central problem for any e-cash system. It's solved in Bitcoin by the immutable ledger: once a transaction is sufficiently confirmed, no miners will verify transactions that reuse the same UTXO. However, it's possible to double-spend _before_ a transaction has been confirmed — which is why you always want one or more confirmations before you finalize a transaction. In the case of RBF, you purposefully double-spend because an initial transaction has stalled, and the miners accept your double-spend if you meet the specific criteria laid out by BIP 125. > :warning: **WARNING:** Some early discussions of this policy suggested that the `nSequence` number also be increased. This in fact was the intended use of `nSequence` in its original form. This is _not_ a part of the published policy in BIP 125. In fact, increasing your sequence number can accidentally lock your transaction with a relative timelock, unless you use sequence numbers in the range of 0xf0000000 (4026531840) to 0xffffffff-2 (4294967293). @@ -139,74 +81,77 @@ In order to create an RBF transaction by hand, all you have to do is create a ra The following example just reuses our existing variables, but decreases the amount sent to the change address, to increase the fee from the accidental 0 BTC of the original transaction to an overly generous 0.01 BTC in the new transaction: ``` -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.1, "'$changeaddress'": 0.89 }''') +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.000075, "'$changeaddress'": 0.00000001 }''') ``` We of course must re-sign it and resend it: ``` $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx -959b0b0f4c8350e9038279dfe0f5ae7b165660cc1281e37bea08d0bd084edb39 +c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b ``` -After several blocks have been created, the original transaction continues to hang around: +You can now look at your original transaction and see that it has `walletconflicts`: ``` -$ bitcoin-cli -named gettransaction txid=7218b78ad4853eb957b610033b8e1ef48b01d948e0ec5dbf79f12caebc2b17e2 +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 { - "amount": -0.10000000, - "fee": 0.00000000, - "confirmations": -5, + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": 0, "trusted": false, - "txid": "7218b78ad4853eb957b610033b8e1ef48b01d948e0ec5dbf79f12caebc2b17e2", + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", "walletconflicts": [ - "959b0b0f4c8350e9038279dfe0f5ae7b165660cc1281e37bea08d0bd084edb39" + "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b" ], - "time": 1491603320, - "timereceived": 1491603320, + "time": 1592954399, + "timereceived": 1592954399, "bip125-replaceable": "yes", "details": [ - { - "account": "", - "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", - "category": "send", - "amount": -0.10000000, - "vout": 0, - "fee": 0.00000000, - "abandoned": false - } ], - "hex": "02000000014e843e22cb8ee522fbf4d8a0967a733685d2ad92697e63f52ce41bec8f7c8ac0010000006b483045022100834731cd64efcc078d6c3e59cf0963599ffbc44722b7851b0404bb68e4a1fec70220759a0887ea791592c8119bbe61842eb3850a20cdf8433b4ba00d4ead752facfe012103456575f59a127a4c3e79c23f185899fa0a9ccd40162d05617fb112fa31bd14e5010000000280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac804a5d05000000001976a914c101d8c34de7b8d83b3f8d75416ffaea871d664988ac00000000" + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" } ``` -Note that `bitcoin-cli` recognizes that there's a conflict with another transaction in the `walletconflicts` section. Also note that this transaction is now listed with _negative confirmations_, which marks how long it's been since the opposing double-spend was confirmed. +This represents the fact that two different transactions are both trying to use the same UTXO. -Meanwhile, the new transaction worked fine: +Eventually, the transaction with the larger fee should be accepted: ``` -$ bitcoin-cli -named gettransaction txid=959b0b0f4c8350e9038279dfe0f5ae7b165660cc1281e37bea08d0bd084edb39 +$ bitcoin-cli -named gettransaction txid=c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b { - "amount": -0.10000000, - "fee": -0.01000000, - "confirmations": 5, - "blockhash": "00000000000006eeb468791e5ee0d86613c03acd871ef7d89c25fd28474754d5", - "blockindex": 20, - "blocktime": 1491603862, - "txid": "959b0b0f4c8350e9038279dfe0f5ae7b165660cc1281e37bea08d0bd084edb39", + "amount": 0.00000000, + "fee": -0.00000299, + "confirmations": 2, + "blockhash": "0000000000000055ac4b6578d7ffb83b0eccef383ca74500b00f59ddfaa1acab", + "blockheight": 1773266, + "blockindex": 9, + "blocktime": 1592955002, + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", "walletconflicts": [ - "7218b78ad4853eb957b610033b8e1ef48b01d948e0ec5dbf79f12caebc2b17e2" + "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375" ], - "time": 1491603673, - "timereceived": 1491603673, + "time": 1592954467, + "timereceived": 1592954467, "bip125-replaceable": "no", "details": [ - { - "account": "", - "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", - "category": "send", - "amount": -0.10000000, - "vout": 0, - "fee": -0.01000000, - "abandoned": false - } ], - "hex": "02000000014e843e22cb8ee522fbf4d8a0967a733685d2ad92697e63f52ce41bec8f7c8ac0010000006a47304402207fea4a11db8576257b9d9e104aa07cb3d3ae6a42e38dd7126111276ca5b45daa0220594a3553cc278c43fd015b35029d5b9596d4ac9f36d3d20fb1a8c9efface5c50012103456575f59a127a4c3e79c23f185899fa0a9ccd40162d05617fb112fa31bd14e5020000000280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac40084e05000000001976a914c101d8c34de7b8d83b3f8d75416ffaea871d664988ac00000000" + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b010000000001000000024c1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077dcdd98d85f6247450185c2b918a0f434d9b2e647330d741944ecae60d6ff790220424f85628cebe0ffe9fa11029b8240d08bdbfcc0c11f799483e63b437841b1cd0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Meanwhile, the original transaction with the lower fee starts picking up negative confirmations, to show its divergence from the blockchain: +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": -2, + "trusted": false, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b" + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" } ``` Our recipients have their money, and the original, failed transaction will eventually fall out of the mempool. From 25b3482469e3494e171b0bb6daf454e4f2902c7d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:04:09 -1000 Subject: [PATCH 100/202] updated for 0.20 --- 05_3_Funding_a_Transaction_with_CPFP.md | 58 ++++++++++++++++--------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/05_3_Funding_a_Transaction_with_CPFP.md b/05_3_Funding_a_Transaction_with_CPFP.md index 8373e9e..6d96a35 100644 --- a/05_3_Funding_a_Transaction_with_CPFP.md +++ b/05_3_Funding_a_Transaction_with_CPFP.md @@ -24,49 +24,67 @@ Funding a transaction with CPFP is a very simple process using the methods you'r ``` $ bitcoin-cli getrawmempool [ - "ed7f68d9e363f710379c83baca1b71360b3a2ceaf62f8414a26b6680f77e132b" + "95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061" ] -$ bitcoin-cli getrawtransaction ed7f68d9e363f710379c83baca1b71360b3a2ceaf62f8414a26b6680f77e132b 1 +$ bitcoin-cli getrawtransaction 95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061 true { - "hex": "02000000010d5151273464ac8fa74c1b57ff8e4650b8e190c488b1cfadae6561ac3988e83c000000006a473044022059c402379c8e7d5bf60840fc75497ee67694e6dfc9b0391c59b4b202edf4194b0220686c5a27bee1a9214e410cbce3d11e47ca57736d7546ba208adcc068a3f826f5012103fb14f31f5f143463198a3e79c7529cae529a32857ada29bec26f7ea9d8ea67f3ffffffff0130e1be07000000001976a914cbecb861750ee3b00ea845f5c1efa72d1c541cec88ac00000000", - "txid": "ed7f68d9e363f710379c83baca1b71360b3a2ceaf62f8414a26b6680f77e132b", - "hash": "ed7f68d9e363f710379c83baca1b71360b3a2ceaf62f8414a26b6680f77e132b", - "size": 191, - "vsize": 191, + "txid": "95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061", + "hash": "9729e47b8aee776112a82cec46df7638d112ca51856c53e238a9b1f7af3be4ce", "version": 2, - "locktime": 0, + "size": 247, + "vsize": 166, + "weight": 661, + "locktime": 1773277, "vin": [ { - "txid": "3ce88839ac6165aeadcfb188c490e1b850468eff571b4ca78fac64342751510d", + "txid": "7a0178472300247d423ac4a04ff9165fa5b944104f6d6f9ebc557c6d207e7524", "vout": 0, "scriptSig": { - "asm": "3044022059c402379c8e7d5bf60840fc75497ee67694e6dfc9b0391c59b4b202edf4194b0220686c5a27bee1a9214e410cbce3d11e47ca57736d7546ba208adcc068a3f826f5[ALL] 03fb14f31f5f143463198a3e79c7529cae529a32857ada29bec26f7ea9d8ea67f3", - "hex": "473044022059c402379c8e7d5bf60840fc75497ee67694e6dfc9b0391c59b4b202edf4194b0220686c5a27bee1a9214e410cbce3d11e47ca57736d7546ba208adcc068a3f826f5012103fb14f31f5f143463198a3e79c7529cae529a32857ada29bec26f7ea9d8ea67f3" + "asm": "0014334f3a112df0f22e743ad97eec8195a00faa59a0", + "hex": "160014334f3a112df0f22e743ad97eec8195a00faa59a0" }, - "sequence": 4294967295 + "txinwitness": [ + "304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae01", + "03574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9" + ], + "sequence": 4294967294 } ], "vout": [ { - "value": 1.29950000, + "value": 0.01000000, "n": 0, "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 cbecb861750ee3b00ea845f5c1efa72d1c541cec OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914cbecb861750ee3b00ea845f5c1efa72d1c541cec88ac", + "asm": "OP_HASH160 f079f77f2ef0ef1187093379d128ec28d0b4bf76 OP_EQUAL", + "hex": "a914f079f77f2ef0ef1187093379d128ec28d0b4bf7687", "reqSigs": 1, - "type": "pubkeyhash", + "type": "scripthash", "addresses": [ - "mz7D3c6tMtNXV6CTsEwDBJ2vhSVTo9bSMN" + "2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5" + ] + } + }, + { + "value": 0.02598722, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 8799be12fb9eae6644659d95b9602ddfbb4b2aff OP_EQUAL", + "hex": "a9148799be12fb9eae6644659d95b9602ddfbb4b2aff87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N5cDPPuCTtYq13oXw8RfpY9dHJW8sL64U2" ] } } - ] + ], + "hex": "0200000000010124757e206d7c55bc9e6f6d4f1044b9a55f16f94fa0c43a427d2400234778017a0000000017160014334f3a112df0f22e743ad97eec8195a00faa59a0feffffff0240420f000000000017a914f079f77f2ef0ef1187093379d128ec28d0b4bf768742a727000000000017a9148799be12fb9eae6644659d95b9602ddfbb4b2aff870247304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae012103574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9dd0e1b00" } ``` Look through the `vout` array. Find the object that matches your address. (Here, it's the only one.) The `n` value is your `vout`. You now have everything you need to create a new CPFP transaction. ``` -$ utxo_txid=ed7f68d9e363f710379c83baca1b71360b3a2ceaf62f8414a26b6680f77e132b +$ utxo_txid=2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5 $ utxo_vout=0 $ recipient2=$(bitcoin-cli getrawchangeaddress) ``` @@ -76,7 +94,7 @@ $ recipient2=$(bitcoin-cli getrawchangeaddress) 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: ``` -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient2'": 1.2985 }''') +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient2'": 0.03597 }''') $ bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex' 02000000012b137ef780666ba214842ff6ea2c3a0b36711bcaba839c3710f763e3d9687fed000000006a473044022003ca1f6797d781ef121ba7c2d1d41d763a815e9dad52aa8bc5ea61e4d521f68e022036b992e8e6bf2c44748219ca6e0056a88e8250f6fd0794dc69f79a2e8993671601210317b163ab8c8862e09c71767112b828abd3852e315441893fa0f535de4fa39b8dffffffff01905abd07000000001976a91450b1d90a130c4f3f1e5fbfa7320fd36b7265db0488ac00000000 From 75721798601e980c775ecfd1c2331fd0d0521b3c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:05:10 -1000 Subject: [PATCH 101/202] chapter 5! --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 23c0fe5..e2438f9 100644 --- a/TODO.md +++ b/TODO.md @@ -26,7 +26,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Edit & Check Chapter 4 **6/23** * Double-check fee calculator in 4.2I with a more complex example **6/19** * Integrate older Curl Interlude **6/19** - * Edit & Check Chapter 5 + * Edit & Check Chapter 5 **6/23** * Edit & Check Chapter 6 ## 3. Add BTCDEB Support From be67dbb49215679d277b4c8039f0d365de379d82 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:08:32 -1000 Subject: [PATCH 102/202] added named to example --- 04_6_Creating_a_Segwit_Transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index 7eb83d7..2aad529 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -22,7 +22,7 @@ You create a SegWit address the same way as any other address, with the `getnewa If you need to create an address for someone who can't send to the newer Bech32 addresses, then use the `p2sh-segwit` addresstype: ``` -$ bitcoin-cli getnewaddress -addresstype p2sh-segwit +$ bitcoin-cli -named getnewaddress address_type=p2sh-segwit 2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN ``` Seeing an address with a "2" prefix means that you did it right. From b5cc6155f00d11436b95dd710939271e756335ff Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:09:53 -1000 Subject: [PATCH 103/202] added segwit mention --- 06_0_Expanding_Bitcoin_Transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/06_0_Expanding_Bitcoin_Transactions.md b/06_0_Expanding_Bitcoin_Transactions.md index 0f0ddf5..59fc82c 100644 --- a/06_0_Expanding_Bitcoin_Transactions.md +++ b/06_0_Expanding_Bitcoin_Transactions.md @@ -1,6 +1,6 @@ # Chapter Six: Expanding Bitcoin Transactions -Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH recipient; (3) immediately. However, all three parts of this definition can be expanded using more complex Bitcoin transactions, which can alternatively send data, which can send to a group of recipients, or which can send at a later time. These three options represent further empowerment of Bitcoin and also the furthest boundaries of what you can do with the basic `bitcoin-cli` command. +Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit recipient; (3) immediately. However, all three parts of this definition can be expanded using more complex Bitcoin transactions, which can alternatively send data, which can send to a group of recipients, or which can send at a later time. These three options represent further empowerment of Bitcoin and also the furthest boundaries of what you can do with the basic `bitcoin-cli` command. ## Objectives for This Section From 056526cfd3b8626e03a2d38552434cbfdd62c548 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:10:45 -1000 Subject: [PATCH 104/202] reformatted power question --- 05_2_Resending_a_Transaction_with_RBF.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_2_Resending_a_Transaction_with_RBF.md b/05_2_Resending_a_Transaction_with_RBF.md index 8c2a701..c2f00b4 100644 --- a/05_2_Resending_a_Transaction_with_RBF.md +++ b/05_2_Resending_a_Transaction_with_RBF.md @@ -208,9 +208,9 @@ $ bitcoin-cli -named gettransaction txid=75208c5c8cbd83081a0085cd050fc7a4064d87c If a transaction is stuck, and you don't want to wait for it to expire entirely, if you opted-in to RBF, then you can double-spend using RBF to create a replacement transaction (or just use `bumpfee`). -_What is the power of RBF?_ Obviously, RBF is very helpful if you created a transaction with too low of a fee and you need to get those funds through. However, the ability to generally replace unconfirmed transactions with updated ones has more power than just that (and is why you might want to continue using RBF with raw transactions, even following the advent of `bumpfee`). +> ***What is the power of RBF?*** Obviously, RBF is very helpful if you created a transaction with too low of a fee and you need to get those funds through. However, the ability to generally replace unconfirmed transactions with updated ones has more power than just that (and is why you might want to continue using RBF with raw transactions, even following the advent of `bumpfee`). -For example, you might send a transaction, and then before it's confirmed, combine it with a second transaction. This allows you to compress multiple transactions down into a single one, decreasing overall fees. It might also offer benefits to privacy. There are other reasons to use RBF too, for smart contracts or transaction cut-throughs, as described in the [Opt-in RBF FAQ](https://bitcoincore.org/en/faq/optin_rbf/). +> For example, you might send a transaction, and then before it's confirmed, combine it with a second transaction. This allows you to compress multiple transactions down into a single one, decreasing overall fees. It might also offer benefits to privacy. There are other reasons to use RBF too, for smart contracts or transaction cut-throughs, as described in the [Opt-in RBF FAQ](https://bitcoincore.org/en/faq/optin_rbf/). ## What's Next? From bd7886864ae342b49b52059b4aa818d80b84b06c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:11:06 -1000 Subject: [PATCH 105/202] re-reformatted power question --- 05_2_Resending_a_Transaction_with_RBF.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_2_Resending_a_Transaction_with_RBF.md b/05_2_Resending_a_Transaction_with_RBF.md index c2f00b4..f1a224e 100644 --- a/05_2_Resending_a_Transaction_with_RBF.md +++ b/05_2_Resending_a_Transaction_with_RBF.md @@ -208,7 +208,7 @@ $ bitcoin-cli -named gettransaction txid=75208c5c8cbd83081a0085cd050fc7a4064d87c If a transaction is stuck, and you don't want to wait for it to expire entirely, if you opted-in to RBF, then you can double-spend using RBF to create a replacement transaction (or just use `bumpfee`). -> ***What is the power of RBF?*** Obviously, RBF is very helpful if you created a transaction with too low of a fee and you need to get those funds through. However, the ability to generally replace unconfirmed transactions with updated ones has more power than just that (and is why you might want to continue using RBF with raw transactions, even following the advent of `bumpfee`). +> :fire: ***What is the power of RBF?*** Obviously, RBF is very helpful if you created a transaction with too low of a fee and you need to get those funds through. However, the ability to generally replace unconfirmed transactions with updated ones has more power than just that (and is why you might want to continue using RBF with raw transactions, even following the advent of `bumpfee`). > For example, you might send a transaction, and then before it's confirmed, combine it with a second transaction. This allows you to compress multiple transactions down into a single one, decreasing overall fees. It might also offer benefits to privacy. There are other reasons to use RBF too, for smart contracts or transaction cut-throughs, as described in the [Opt-in RBF FAQ](https://bitcoincore.org/en/faq/optin_rbf/). From 69e01c6fd90a56f7e396b57baff82aa38d4832a2 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:11:59 -1000 Subject: [PATCH 106/202] reformatted power question --- 05_3_Funding_a_Transaction_with_CPFP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_3_Funding_a_Transaction_with_CPFP.md b/05_3_Funding_a_Transaction_with_CPFP.md index 6d96a35..8417912 100644 --- a/05_3_Funding_a_Transaction_with_CPFP.md +++ b/05_3_Funding_a_Transaction_with_CPFP.md @@ -122,7 +122,7 @@ A _recipient_ could use CPFP even if he wasn't planning on immediately spending You can take advantage of the CPFP incentives to free up funds that have been sent to you but have not been confirmed. Just use the unconfirmed transaction as UTXO and pay a higher-than-average transaction fee. -_What is the power of CPFP?_ Mostly, CPFP is just useful to get funds unstuck when you're the recipient and the sender isn't being helpful for whatever reason. It doesn't have the more powerful possibilities of RBF, but is an alternatve way to exert control over a transaction after it's been placed in the mempool, but before it's confirmed in a block. +> :fire: ***What is the power of CPFP?*** Mostly, CPFP is just useful to get funds unstuck when you're the recipient and the sender isn't being helpful for whatever reason. It doesn't have the more powerful possibilities of RBF, but is an alternatve way to exert control over a transaction after it's been placed in the mempool, but before it's confirmed in a block. ## What's Next? From ebb250d5c5cc96828fa39ae8c9bd71b7dd624edd Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 14:34:56 -1000 Subject: [PATCH 107/202] update for 0.20 --- 06_1_Sending_a_Transaction_to_a_Multisig.md | 100 +++++++++----------- 1 file changed, 45 insertions(+), 55 deletions(-) diff --git a/06_1_Sending_a_Transaction_to_a_Multisig.md b/06_1_Sending_a_Transaction_to_a_Multisig.md index 519966b..b928787 100644 --- a/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -6,17 +6,17 @@ 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 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. -_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. +> :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. [§8.4: Scripting a Multisig](08_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 address, but multiple private keys will be required for the redemption of the funds. -_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. +> :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. Simple multisignatures require everyone in the group to sign the UTXO when it's spent. However, there's more complexity possible. Multisignatures are generally described as being "m of n". That means that the transaction is locked with a group of "n" keys, but only "m" of them are required to unlock the transaction. -_What is a m-of-n multisignature?_ In a multisignature, "m" signatures out of a group of "n" are required to form the signature, where "m ≤ n". +> :book: ***What is a m-of-n multisignature?*** In a multisignature, "m" signatures out of a group of "n" are required to form the signature, where "m ≤ n". ## Create a Multisig Address @@ -24,7 +24,7 @@ In order to lock a UTXO with multiple private keys, you must first create a mult ### Create the Addresses -To create a multisignature address, you must first ready the P2PKH addresses that the multisig will combine. Best practice suggests that you always create new addresses. This means that the participants will each run the `getnewaddress` command on their own machine: +To create a multisignature address, you must first ready the addresses that the multisig will combine. Best practice suggests that you always create new addresses. This means that the participants will each run the `getnewaddress` command on their own machine: ``` machine1$ address1=$(bitcoin-cli getnewaddress) ``` @@ -44,41 +44,28 @@ Over on the remote machine, which we assume here is `machine2`, you can get the ``` machine2$ bitcoin-cli -named getaddressinfo address=$address2 { - "address": "2N9Qnf7kGS5QX8mRDFQv7QWARFRqkKdp9pN", - "scriptPubKey": "a914b15107009c65b631226d0626b22150098c91d35587", + "address": "tb1qr2tkjh8rs9xn5xaktf5phct0wxqufplawrfd9q", + "scriptPubKey": "00141a97695ce3814d3a1bb65a681be16f7181c487fd", "ismine": true, "solvable": true, - "desc": "sh(wpkh([801811ed/0'/0'/4']0373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f4))#rxfcwarv", + "desc": "wpkh([fe6f2292/0'/0'/1']02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3)#zc64l8dw", "iswatchonly": false, - "isscript": true, - "iswitness": false, - "script": "witness_v0_keyhash", - "hex": "0014c06d895303bd7dff0320d7df9f33f99e8b9b0d93", - "pubkey": "0373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f4", - "embedded": { - "isscript": false, - "iswitness": true, - "witness_version": 0, - "witness_program": "c06d895303bd7dff0320d7df9f33f99e8b9b0d93", - "pubkey": "0373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f4", - "address": "tb1qcpkcj5crh47l7qeq6l0e7vlen69ekrvn509duc", - "scriptPubKey": "0014c06d895303bd7dff0320d7df9f33f99e8b9b0d93" - }, - "label": "", + "isscript": false, + "iswitness": true, + "witness_version": 0, + "witness_program": "1a97695ce3814d3a1bb65a681be16f7181c487fd", + "pubkey": "02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3", "ischange": false, - "timestamp": 1579204237, - "hdkeypath": "m/0'/0'/4'", - "hdseedid": "67ffe46aa0cfd46eb342b78579f72fd1597833b4", - "hdmasterfingerprint": "801811ed", + "timestamp": 1592957904, + "hdkeypath": "m/0'/0'/1'", + "hdseedid": "1dc70547f2b80e9bb5fde5f34fb3d85f8d8d1dab", + "hdmasterfingerprint": "fe6f2292", "labels": [ - { - "name": "", - "purpose": "receive" - } + "" ] } ``` -The `pubkey` address (`0373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f4`) is what's required. Copy it over to your local machine by whatever means you find most efficient and _least error prone_. +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. @@ -93,27 +80,28 @@ machine1$ pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r A multisig can now be created with the `createmultisig` command: ``` -machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","0373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f4"]''' +machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]''' { - "address": "2NDU6abQtzh4LcNs4Vd7WQJwZhkXSt1aZGM", - "redeemScript": "522103f92e9f4c83f4438c86814952ab28836b6e3bfb38089a1f23ff8869eaf217982c210373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f452ae" + "address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "redeemScript": "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae", + "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" } ``` > :warning: **VERSION WARNING:** Older versions of `createmultisig` allowed you to enter an address instead of a public key, if the full information about the address was in your local wallet. This is no longer the case for modern Bitcoin core release, and so the shorthand should not be used. -When creating the multisignature address, you list how many signatures are required with the `nrequired` argument (that's "m" in a "m-of-n" multisignature), then you list the total set of possible signatures with the `keys` argument (that's "n"). Note that the the `keys` entries likely came from different places. In this case, we included `$pubkey1` from the local machine and `0373de7b25896556c33e7a6f5379151291d380c60b84c3ee9a8c933b08ce0da9f4` from a remote machine. +When creating the multisignature address, you list how many signatures are required with the `nrequired` argument (that's "m" in a "m-of-n" multisignature), then you list the total set of possible signatures with the `keys` argument (that's "n"). Note that the the `keys` entries likely came from different places. In this case, we included `$pubkey1` from the local machine and `02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3` from a remote machine. > :information_source: **NOTE — M-OF-N VS N-OF-N:** This example shows the creation of a simple 2-of-2 multisig. If you instead want to create an m-of-n signature where "m < n", you adjust the `nrequired` field and/or the number of signatures in the `keys` JSON object. For a 1-of-2 multisig, you'd set `nrequired=1`, while for a 2-of-3 multisig, you'd leave `nrequired=2`, but add one more public key or address to the `keys` listing. When used correctly, `createmultisig` returns two results, both of which are critically important. -The _address_ is what you'll give out to people who want to send funds. You'll notice that it has a new prefix of `2`, rather than the prefixes you've seen on Bitcoin addresses to date. That's because `createmultisig` is actually creating a totally new type of address called a P2SH address. It works exactly like a standard P2PKH address for sending funds, but you'll need to do a lot more work to spend them. +The _address_ is what you'll give out to people who want to send funds. You'll notice that it has a new prefix of `2`, exactly like those P2SH-SegWit addresses. That's because, like them, `createmultisig` is actually creating a totally new type of address called a P2SH address. It works exactly like a standard P2PKH address for sending funds, but since this one has been built to require multiple addresses, you'll need to do a lot more work to spend them. > :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 [§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. -_What is a P2SH address?_ P2SH stands for Pay-to-script-hash. It's a different type of receipient than a standard P2PKH address, 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". +> :book: ***What is a P2SH address?*** P2SH stands for Pay-to-script-hash. It's a different type of receipient 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 actually 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. @@ -124,7 +112,7 @@ Here's an important caveat: nothing about your multisig is saved into your walle * A list of the Bitcoin addresses used in the multisig. * The `redeemScript` output by `createmultsig`. -Technically, the `redeemScript` can be recreated by rerunning `createmultisig` with the complete list of addresses and/or public keys _in the same order_ and with the right m-of-n count. But, it's better to hold onto it and save yourself stress and grief. +Technically, the `redeemScript` can be recreated by rerunning `createmultisig` with the complete list of public keys _in the same order_ and with the right m-of-n count. But, it's better to hold onto it and save yourself stress and grief. ## Send to a Multisig Address @@ -132,20 +120,21 @@ If you've got a multisignature in a convenient P2SH format, like the one generat ``` $ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') -$ recipient="2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz" +$ recipient="2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 1.2995}''') +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.000065}''') $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex { - "txid": "ad16ea68a62af2d3930a48c5ca811bf66935f768bb369a85298ee6697167c667", - "hash": "ad16ea68a62af2d3930a48c5ca811bf66935f768bb369a85298ee6697167c667", + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "hash": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "version": 2, "size": 83, "vsize": 83, - "version": 2, + "weight": 332, "locktime": 0, "vin": [ { - "txid": "ad16098f5c8904a4de7c152efc56359c22be37d447cd78019c398791a7bdd928", + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", "vout": 0, "scriptSig": { "asm": "", @@ -156,31 +145,32 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex ], "vout": [ { - "value": 1.29950000, + "value": 0.00006500, "n": 0, "scriptPubKey": { - "asm": "OP_HASH160 babf9063cee8ab6e9334f95f6d4e9148d0e551c2 OP_EQUAL", - "hex": "a914babf9063cee8ab6e9334f95f6d4e9148d0e551c287", + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", "reqSigs": 1, "type": "scripthash", "addresses": [ - "2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz" + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" ] } } ] } -$ signedtx=$(bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex') + +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx -621be11aac439d6ec58be398058fc33c3e89cf45138a0e73e05b7001f9b6e328 +b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 ``` -As you can see, there was nothing unusual in the creation of the transaction, and it looked entirely normal, albeit with an address with a different prefix than normal (`2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz`). +As you can see, there was nothing unusual in the creation of the transaction, and it looked entirely normal, albeit with an address with a different prefix than normal (`2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr`). No surprise, as we similarly saw no difference when we sent to Bech32 addresses for the first time in [§4.6](04_6_Creating_a_Segwit_Transaction.md). ## Summary: Sending a Transaction with a Multisig -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 will get more coverage in the future. +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. -_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 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. ## What's Next? From 4a4e2ecd263a1eb40bc3908748005cdb83aa90a7 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 15:11:07 -1000 Subject: [PATCH 108/202] updated for 0.20 --- 06_2_Spending_a_Transaction_to_a_Multisig.md | 134 ++++++++++++++----- 1 file changed, 97 insertions(+), 37 deletions(-) diff --git a/06_2_Spending_a_Transaction_to_a_Multisig.md b/06_2_Spending_a_Transaction_to_a_Multisig.md index facc83b..10fa66f 100644 --- a/06_2_Spending_a_Transaction_to_a_Multisig.md +++ b/06_2_Spending_a_Transaction_to_a_Multisig.md @@ -10,48 +10,103 @@ To start with, you need to find your funds; your computer doesn't know to look f ``` $ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz ``` -This command can take a while to run because it does a `rescan` to find all the related transactions. Afterward the funds should show up when you `listunspent` ... but they still aren't easily spendable. +Here's the catch: you can't do this if you have a pruned node! This command can take a while to run because it does a `rescan` to find all the related transactions. Afterward the funds should show up when you `listunspent` ... but they still aren't easily spendable. (In fact, your wallet may claim they're not `spendable` at all!) + +If you're not able to incorporate the address into your wallet due to pruning, using `gettransaction` to get info instead (or look on a block explorer). ``` -$ bitcoin-cli listunspent -[ - { - "txid": "621be11aac439d6ec58be398058fc33c3e89cf45138a0e73e05b7001f9b6e328", - "vout": 0, - "address": "2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz", - "account": "", - "scriptPubKey": "a914babf9063cee8ab6e9334f95f6d4e9148d0e551c287", - "amount": 1.29950000, - "confirmations": 62, - "spendable": false, - "solvable": false +$ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 verbose=true +{ + "amount": -0.00006500, + "fee": -0.00001000, + "confirmations": 3, + "blockhash": "0000000000000165b5f602920088a7e36b11214161d6aaebf5229e3ed4f10adc", + "blockheight": 1773282, + "blockindex": 9, + "blocktime": 1592959320, + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "walletconflicts": [ + ], + "time": 1592958753, + "timereceived": 1592958753, + "bip125-replaceable": "no", + "details": [ + { + "address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "category": "send", + "amount": -0.00006500, + "vout": 0, + "fee": -0.00001000, + "abandoned": false + } + ], + "hex": "020000000001011b95a6055174ec64b82ef05b6aefc38f34d0e57197e40281ecd8287b4260dec60000000000ffffffff01641900000000000017a914a5d106eb8ee51b23cf60d8bd98bc285695f233f38702473044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d0012102883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb00000000", + "decoded": { + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "hash": "bdf4e3bc5d354a5dfa5528f172480976321d989d7e5806ac14f1fe9b0b1c093a", + "version": 2, + "size": 192, + "vsize": 111, + "weight": 441, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "3044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d001", + "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00006500, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } + } + ] } -] +} ``` -(In fact, your wallet claims they're not `spendable` at all!) ## Set Up Your Variables -When you're ready to spend the funds received by a multisignature address, you're going need to collect a _lot_ of data: much more than you need when you spend a normal P2PKH UTXO. That's in part because the info on the multisig address isn't in your wallet, and in part because you're spending money that was sent to a P2SH (pay-to-script-hash) address, and that's a lot more demanding. +When you're ready to spend the funds received by a multisignature address, you're going need to collect a _lot_ of data: much more than you need when you spend a normal P2PKH or SegWit UTXO. That's in part because the info on the multisig address isn't in your wallet, and in part because you're spending money that was sent to a P2SH (pay-to-script-hash) address, and that's a lot more demanding. In total, you're going to need to collect three things: extended information about the UTXO; the redeemScript; and all the private keys involved. You'll of course need a new recipient address too. The private keys need to wait for the signing step, but everything else can be done now. ### Access the UTXO information -To start with, grab the `txid` and the `vout` for the transaction that you want to spend, as usual. For example, if it's your 0th UTXO: +To start with, grab the `txid` and the `vout` for the transaction that you want to spend, as usual. In this case, it was retrieved from the `gettransaction` info, above: ``` -$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') -$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 +$ utxo_vout=0 ``` -However, you need to also access a third bit of information about the UTXO, its `scriptPubKey`, which is the script that locked the transaction. This is done with a simple `bitcoin-cli`/`jq` invocation that mirrors the previous commands. +However, you need to also access a third bit of information about the UTXO, its `scriptPubKey`/`hex`, which is the script that locked the transaction. Again, you're probably doing this by looking at the details of the transaction: ``` -$ utxo_spk=$(bitcoin-cli listunspent | jq -r '.[0] | .scriptPubKey') +$ utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 ``` ### Record the Redeem Script Hopefully, you saved the `redeemScript`. Now you should record it in a variable. + +This was drawn from our creation of the address in the previous section. ``` -$ redeem_script="52210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd819210367c4f666f18279009c941e57fab3e42653c6553e5ca092c104d1db279e328a2852ae" +redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" ``` ### Decide Your Recipient @@ -63,7 +118,9 @@ $ recipient=$(bitcoin-cli getrawchangeaddress) You can now create your transaction. This is no different than usual. ``` -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 1.299}''') +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +$ echo $rawtxhex +020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 ``` ## Sign Your Transaction @@ -75,7 +132,7 @@ You're now ready to sign your transaction. This is a multi-step process because Because this transaction isn't making full use of your wallet, you're going to need to directly access your private keys. Start on `machine1`, where you should retrieve any of that user's private keys that were involved in the multisig: ``` machine1$ bitcoin-cli -named dumpprivkey address=$address1 -cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw +cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR ``` > :warning: **WARNING:** Directly accessing your private keys from the shell is very dangerous behavior and should be done with extreme care if you're using real money. At the least, don't save the information into a variable that could be accessed from your machine. Removing your shell's history is another great step. At the most, don't do it. @@ -87,51 +144,54 @@ You can now make your first signature with the `signrawtransactionwithkey` comma * Include a `privkeys` argument that lists the private keys you dumped on this machine. ``` -machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"]' +machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]' { - "hex": "020000000128e3b6f901705be0730e8a1345cf893e3cc38f0598e38bc56e9d43ac1ae11b62000000009200483045022100a9fe6ed0dbe14c0c4c7c89cee0aef2770f0b2bdcd6b3e8d71fe91e91c4bb765e02200cfba27a59b584a0cc8e70fb4438be94da417ee77eff28deb70449e012b6d6fa014752210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd819210367c4f666f18279009c941e57fab3e42653c6553e5ca092c104d1db279e328a2852aeffffffff01e01dbe07000000001976a914cd1b2ba4fa8ae3e62bc4fc6be467a63228ceeedf88ac00000000", + "hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000", "complete": false, "errors": [ { - "txid": "621be11aac439d6ec58be398058fc33c3e89cf45138a0e73e05b7001f9b6e328", + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", "vout": 0, - "scriptSig": "00483045022100a9fe6ed0dbe14c0c4c7c89cee0aef2770f0b2bdcd6b3e8d71fe91e91c4bb765e02200cfba27a59b584a0cc8e70fb4438be94da417ee77eff28deb70449e012b6d6fa014752210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd819210367c4f666f18279009c941e57fab3e42653c6553e5ca092c104d1db279e328a2852ae", + "witness": [ + ], + "scriptSig": "0047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae", "sequence": 4294967295, - "error": "Operation not valid with the current stack size" + "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)" } ] } + ``` -That produces scary errors and says that it's not `complete`. This is all correct. You can see that the signature has been partially successfully because the `hex` has gotten longer. Though the transaction has been partially signed, it's not done because it needs more signatures. +That produces scary errors and says that it's not `failing`. This is all correct. You can see that the signature has been partially successfully because the `hex` has gotten longer. Though the transaction has been partially signed, it's not done because it needs more signatures. ### 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 (`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 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. > :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. To do so first they access their private keys: ``` -$ bitcoin-cli -named dumpprivkey address=$address2 -cTi1Muvj24vG159R8orFjtqsPygCxhu8mJt2GLDQv7bNBGYoav4B +machine2$ bitcoin-cli -named dumpprivkey address=$address2 +cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz ``` Second, they sign the new `hex` using all the same `prevtxs` values: ``` -$ bitcoin-cli -named signrawtransactionwithkey hexstring=020000000128e3b6f901705be0730e8a1345cf893e3cc38f0598e38bc56e9d43ac1ae11b62000000009200483045022100a9fe6ed0dbe14c0c4c7c89cee0aef2770f0b2bdcd6b3e8d71fe91e91c4bb765e02200cfba27a59b584a0cc8e70fb4438be94da417ee77eff28deb70449e012b6d6fa014752210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd819210367c4f666f18279009c941e57fab3e42653c6553e5ca092c104d1db279e328a2852aeffffffff01e01dbe07000000001976a914cd1b2ba4fa8ae3e62bc4fc6be467a63228ceeedf88ac00000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cTi1Muvj24vG159R8orFjtqsPygCxhu8mJt2GLDQv7bNBGYoav4B"]' +machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' { - "hex": "020000000128e3b6f901705be0730e8a1345cf893e3cc38f0598e38bc56e9d43ac1ae11b6200000000db00483045022100a9fe6ed0dbe14c0c4c7c89cee0aef2770f0b2bdcd6b3e8d71fe91e91c4bb765e02200cfba27a59b584a0cc8e70fb4438be94da417ee77eff28deb70449e012b6d6fa01483045022100d5190eb824535423f67b15040efaba66953ea39f312540dd38504ed85ba6436402206171883ff28c235030550c36cadb31e40aaa9a74f71579557b74a5684545675c014752210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd819210367c4f666f18279009c941e57fab3e42653c6553e5ca092c104d1db279e328a2852aeffffffff01e01dbe07000000001976a914cd1b2ba4fa8ae3e62bc4fc6be467a63228ceeedf88ac00000000", + "hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000d90047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e301473044022000a402ec4549a65799688dd531d7b18b03c6379416cc8c29b92011987084e9f402205470e24781509c70e2410aaa6d827aa133d6df2c578e96a496b885584fb039200147522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000", "complete": true } ``` Third, they may need to send on the even longer `hexstring` they produce to additional signers. -In this case, we now see that the signature is `complete`! +But in this case, we now see that the signature is `complete`! ## Send Your Transaction When done, you should fall back on the standard JQ methodology to save your `hexstring` and then to send it: ``` -$ signedtx = $(bitcoin-cli -named signrawtransactionwithkey hexstring=020000000128e3b6f901705be0730e8a1345cf893e3cc38f0598e38bc56e9d43ac1ae11b62000000009200483045022100a9fe6ed0dbe14c0c4c7c89cee0aef2770f0b2bdcd6b3e8d71fe91e91c4bb765e02200cfba27a59b584a0cc8e70fb4438be94da417ee77eff28deb70449e012b6d6fa014752210307fd375ed7cced0f50723e3e1a97bbe7ccff7318c815df4e99a59bc94dbcd819210367c4f666f18279009c941e57fab3e42653c6553e5ca092c104d1db279e328a2852aeffffffff01e01dbe07000000001976a914cd1b2ba4fa8ae3e62bc4fc6be467a63228ceeedf88ac00000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cTi1Muvj24vG159R8orFjtqsPygCxhu8mJt2GLDQv7bNBGYoav4B"]' | jq -r '.hex') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' | jq -r .hex) $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx 99d2b5717fed8875a1ed3b2827dd60ae3089f9caa7c7c23d47635f6f5b397c04 ``` From d7c415b1cedb10e5a34c0412f569eb078425d29b Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 15:32:19 -1000 Subject: [PATCH 109/202] updated to 0.20 --- 06_3_Sending_an_Automated_Multisig.md | 52 ++++++++++++++++++--------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/06_3_Sending_an_Automated_Multisig.md b/06_3_Sending_an_Automated_Multisig.md index d1b5c68..510f0c5 100644 --- a/06_3_Sending_an_Automated_Multisig.md +++ b/06_3_Sending_an_Automated_Multisig.md @@ -16,28 +16,36 @@ You start off creating P2PKH addresses and retrieving public keys as usual, for ``` machine1$ address3=$(bitcoin-cli getnewaddress) machine1$ echo $address3 -mkMkhbUzcSPdEHUoRQkBKHe8otP1SzWWeb +tb1q4ep2vmakpkkj6mflu94x5f94q662m0u5ad0t4w machine1$ bitcoin-cli -named getaddressinfo address=$address3 | jq -r '. | .pubkey' -02e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba4 +0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc machine2$ address4=$(bitcoin-cli getnewaddress) $ echo $address4 -mkyeUBPDoeyFrfLE4V5oAQfee99pT2W1E3 +tb1qa9v5h6zkhq8wh0etnv3ae9cdurkh085xufl3de $ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '. | .pubkey' -030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e07776 +02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f ``` ### Create the Multisig Address Everywhere Next you create the multisig on _each machine that contributes signatures_ using a new command, `addmultisigaddress`, instead of `createmultisig`. This new command saves some of the information into your wallet, making it a lot easier to spend the money afterward. ``` -machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e07776"]''' -2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 +machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f"]''' +{ + "address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex", + "redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/15']0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[e9594be8]02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#wxn4tdju" +} -machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["02e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba4","'$address4'"]''' -2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 +machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc","'$address4'"]''' +{ + "address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex", + "redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae", + "descriptor": "wsh(multi(2,[ae42a66f]0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[fe6f2292/0'/0'/2']02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#cc96c5n6" +} ``` -As noted in the previous section, it doesn't matter whether you use addresses or public keys: you'll get the same multisig address. However, you must use the same order. Thus, it's best for the members of the multisig to check amongst themselves to make sure they all got the same result. +As noted in the previous section, it doesn't matter whether you use addresses or public keys: you'll get the same multisig address. However, _you must use the same order_. Thus, it's best for the members of the multisig to check amongst themselves to make sure they all got the same result. ### Watch for Funds @@ -47,6 +55,7 @@ machine1$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAo machine2$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 ``` +(Or use other means if they have a pruned node.) ## Respend with an Automated Transaction @@ -54,32 +63,41 @@ Afterward, you will be able to receive funds on the multisiganture address as no But, it makes life a lot easier. Because everything is in 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. -You start by collecting your variables, but you no longer need to worry about `scriptPubKey` or `redeemScript`: +You start by collecting your variables, but you no longer need to worry about `scriptPubKey` or `redeemScript`. + +Here's a new transaction sent to our new multisig address: ``` -machine1$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') -machine1$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +machine1$ utxo_txid=b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc +machine1$ utxo_vout=0 machine1$ recipient=$(bitcoin-cli getrawchangeaddress) ``` You create a raw transaction: ``` -machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 1.2995}''') +machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') ``` Then you sign it: ``` machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex { - "hex": "02000000014ecda61c45f488e35c613a7c4ae26335a8d7bfd0a942f026d0fb1050e744a67d000000009100473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652aeffffffff0130e1be07000000001976a9148dfbf103e48df7d1993448aa387dc31a2ebd522d88ac00000000", + "hex": "02000000000101bcacf598ccaf9d34f8a057eb4be02e8865f817434a41666a9d15f86e75c4f3b90000000000ffffffff0188130000000000001600144f93c831ec739166ea425984170f4dc6bac75829040047304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01004752210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae00000000", "complete": false, "errors": [ { - "txid": "7da644e75010fbd026f042a9d0bfd7a83563e24a7c3a615ce388f4451ca6cd4e", + "txid": "b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc", "vout": 0, - "scriptSig": "00473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652ae", + "witness": [ + "", + "304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01", + "", + "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae" + ], + "scriptSig": "", "sequence": 4294967295, - "error": "Operation not valid with the current stack size" + "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)" } ] } + ``` Note that you no longer had to give `signrawtransactionwithkey` extra help, because all of that extra information was already in your wallet. Most importantly, you didn't make your private keys vulnerable by directly manipulating them. Instead the process was _exactly_ the same as respending a normal UTXO, except that the transaction wasn't fully signed at the end. From 8e207f8cec211d5a4de0536ff294da9802519273 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 23 Jun 2020 15:36:58 -1000 Subject: [PATCH 110/202] finished for the day --- TODO.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index e2438f9..85991e8 100644 --- a/TODO.md +++ b/TODO.md @@ -27,7 +27,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Double-check fee calculator in 4.2I with a more complex example **6/19** * Integrate older Curl Interlude **6/19** * Edit & Check Chapter 5 **6/23** - * Edit & Check Chapter 6 + * Edit & Check Chapter 6 **6.1, 6.2, 6.3 done** ## 3. Add BTCDEB Support @@ -54,7 +54,9 @@ Add and document the following new concepts: * Integrate discussions of SegWit into early parts of chapter 4. **6/23** * Write chapter 4.6 **6/23** 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). -13. Add Wallet Updates. Some improvements have been made to wallet functionality, including Bitcoin Descriptors, and they should be added to the course. +13. Add Wallet Updates. + * Bitcoin Descriptors + * Key Ordering 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). ## 5. Finish Later Chapters From f5d35a1b100af8b789a3471ee86cf4a799e54d69 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 09:39:06 +0200 Subject: [PATCH 111/202] Update 15_1_Accessing_Bitcoind_with_C.md --- 15_1_Accessing_Bitcoind_with_C.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/15_1_Accessing_Bitcoind_with_C.md b/15_1_Accessing_Bitcoind_with_C.md index bd10a39..1267f2d 100644 --- a/15_1_Accessing_Bitcoind_with_C.md +++ b/15_1_Accessing_Bitcoind_with_C.md @@ -275,7 +275,7 @@ Successfully connected to server! ``` ## Appendix II: Getting Mining Info -Here's the complete code for the `getmininginfo` command, with organized variable initiatialization, error checking, and variable cleanup. For this example we use a regtest network and show it's output. +Here's the complete code for the `getmininginfo` command, with organized variable initiatialization, error checking, and variable cleanup. For this example we use a testnet network and show it's output. ``` file: getmininginfo.c @@ -359,25 +359,25 @@ $ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo $ ./getmininginfo Full Response: { "result": { - "blocks": 1100, - "difficulty": 4.6565423739069252e-10, - "networkhashps": 0.01006838108822419, - "pooledtx": 1, - "chain": "regtest", - "warnings": "" + "blocks": 1773353, + "difficulty": 10178811.406987719, + "networkhashps": 129510207940932.2, + "pooledtx": 9, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" }, "error": null, - "id": "d07a55cc-000a-469e-ad7f-c8cef46644da" + "id": "6e502927-b065-486a-8182-bc1acd843bae" } Just the Result: { - "blocks": 1100, - "difficulty": 4.6565423739069252e-10, - "networkhashps": 0.01006838108822419, - "pooledtx": 1, - "chain": "regtest", - "warnings": "" + "blocks": 1773353, + "difficulty": 10178811.406987719, + "networkhashps": 129510207940932.2, + "pooledtx": 9, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" } -Block Count: 1100 +Block Count: 1773353 ``` From 9b0886c34d0e4084a2d6e9ac3f320d43cbc1ac21 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 11:09:33 +0200 Subject: [PATCH 112/202] Update 15_2_Programming_Bitcoind_with_C.md --- 15_2_Programming_Bitcoind_with_C.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15_2_Programming_Bitcoind_with_C.md b/15_2_Programming_Bitcoind_with_C.md index 1dcd416..370e35d 100644 --- a/15_2_Programming_Bitcoind_with_C.md +++ b/15_2_Programming_Bitcoind_with_C.md @@ -64,7 +64,7 @@ float tx_total = tx_amount + tx_fee; ### X. Prepare Your RPC -Obviously, you're going to need to get all of your variables ready again, as discussed in [§12.2: Accessing Bitcoind with C](12_2_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 [§12.2: 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: ``` bitcoinrpc_global_init(); rpc_client = bitcoinrpc_cl_init_params ("bitcoinrpc", "73bd45ba60ab8f9ff9846b6404769487", "127.0.0.1", 18332); From 8de7475d37e3c928603dc0491825fd787aaffd81 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 11:09:58 +0200 Subject: [PATCH 113/202] Update 15_2_Programming_Bitcoind_with_C.md --- 15_2_Programming_Bitcoind_with_C.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15_2_Programming_Bitcoind_with_C.md b/15_2_Programming_Bitcoind_with_C.md index 370e35d..cdaf8b4 100644 --- a/15_2_Programming_Bitcoind_with_C.md +++ b/15_2_Programming_Bitcoind_with_C.md @@ -64,7 +64,7 @@ float tx_total = tx_amount + tx_fee; ### X. Prepare Your RPC -Obviously, you're going to need to get all of your variables ready again, as discussed in [§12.2: 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 [§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: ``` bitcoinrpc_global_init(); rpc_client = bitcoinrpc_cl_init_params ("bitcoinrpc", "73bd45ba60ab8f9ff9846b6404769487", "127.0.0.1", 18332); From a58385d5fac493f0c50e0544cf816567d6558e04 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 13:16:49 +0200 Subject: [PATCH 114/202] Update 15_2_Programming_Bitcoind_with_C.md --- 15_2_Programming_Bitcoind_with_C.md | 42 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/15_2_Programming_Bitcoind_with_C.md b/15_2_Programming_Bitcoind_with_C.md index cdaf8b4..2c410a6 100644 --- a/15_2_Programming_Bitcoind_with_C.md +++ b/15_2_Programming_Bitcoind_with_C.md @@ -11,10 +11,11 @@ We're going to program a simplistic first cut version of `sendtoaddress`, which 1. Request an address and an amount 2. Set an arbitrary fee 3. Find a UTXO that's large enough for the amount + the fee - 4. Create a change address - 5. Create a raw transaction that sends from the UTXO to the address and the change address - 6. Sign the transaction - 7. Send the transaction + 4. Create a bench 32 address + 5. Create a change address + 6. Create a raw transaction that sends from the UTXO to the address and the change address + 7. Sign the transaction + 8. Send the transaction ### Plan for Your Future @@ -152,7 +153,24 @@ if (!tx_id) { > **WARNING:** A real program would use subroutines for this sort of lookup, so that you could confidentally call various RPCs from a library of C functions. We're just going to blob it all into `main` as part of our KISS philosophy of simple examples. -### 4. Create a Change Address +### 4. Create a Bech32 Address + +Repeat the standard RPC-lookup methodology to get a new address using get new address method. +``` + lu_response = bitcoinrpc_resp_get (btcresponse); + lu_result = json_object_get(lu_response,"result"); + char *address = strdup(json_string_value(lu_result)); + printf("adress %s \n", address); +``` + +Output +``` +$ cc getaddress.c -lbitcoinrpc -ljansson -o getaddress +$ ./getaddress +adress tb1qpxlguwckkqalcg6xrv4ujlmkzqe79nkngcvudf +``` + +### 5. Create a Change Address Repeat the standard RPC-lookup methodology to get a change address: ``` @@ -183,7 +201,7 @@ The only difference is in what particular information we extract from our JSON o > **WARNING:** Here's another place that a subroutine would be really nice: to abstract out the whole RPC method initialization and call. -### 5. Create a Raw Transaction +### 6. Create a Raw Transaction Creating the actual raw transaction is the other tricky part of programming your `sendtoaddress` replacement. That's because it requires the creation of a complex JSON object as a paramter. @@ -194,7 +212,7 @@ createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex" ``` To review, your inputs will be a JSON array containing one JSON object for each UTXO. Then the ouputs will all be in one JSON object. It's easiest to create these JSON elements from the inside out, using `jansson` commands. -#### 5.1. Create the Input Parameters +#### 6.1. Create the Input Parameters To create the input object for your UTXO, use `json_object`, then fill it with key-values using either `json_object_set_new` (for newly created references) or `json_object_set` (for existing references): ``` @@ -213,7 +231,7 @@ inputparams = json_array(); json_array_append(inputparams,inputtxid); ``` -#### 5.2 Create the Output Parameters +#### 6.2 Create the Output Parameters To create the output array for your transaction, follow the same format, creating a JSON object with `json_object`, then filling it with `json_object_set`: ``` @@ -231,7 +249,7 @@ json_object_set(outputparams, changeaddress, json_string(tx_change_string)); > **WARNING:** You might expect to input your Bitcoin values as numbers, using `json_real`. Unfortunately, this exposes one of the major problems with integrating the `jansson` library and Bitcoin. Bitcoin is only valid to eight significant digits past the decimal point. You might recall that .00000001 BTC is a satoshi, and that's the smallest possible division of a Bitcoin. Doubles in C offer more significant digits than that, though they're often imprecise out past eight decimals. If you try to convert straight from your double value in C (or a float value, for that matter) to a Bitcoin value, the imprecision will often create a Bitcoin value with more than eight significant digits. Before Bitcoin Core 0.12 this appears to work, and you could use `json_real`. But as of Bitcoin Core 0.12, if you try to give `createrawtransaction` a Bitcoin value with too many significant digits, you'll instead get an error and the transaction will not be created. As a result, if the Bitcoin value has _ever_ become a double or float, you must reformat it to eight significant digits past the digit before feeding it in as a string. This is obviously a kludge, so you should make sure it continues to work in future versions of Bitcoin Core. -#### 5.3 Create the Parameter Array +#### 6.3 Create the Parameter Array To finish creating your parameters, simply to bundle them all up in a JSON array: ``` @@ -240,7 +258,7 @@ params = json_array(); json_array_append(params,inputparams); json_array_append(params,outputparams); ``` -#### 5.4 Make the RPC Call +#### 6.4 Make the RPC Call Use the normal method to create your RPC call: ``` @@ -263,7 +281,7 @@ lu_result = json_object_get(lu_response,"result"); char *tx_rawhex = strdup(json_string_value(lu_result)); ``` -### 6. Sign the Transaction +### 7. Sign the Transaction It's a lot easier to assign a simple parameter to a function. You just create a JSON array, then assign the parameter to the array: ``` @@ -294,7 +312,7 @@ json_decref(lu_signature); > ***WARNING:*** A real-world program would obviously carefully test the response of every RPC command to make sure there were no errors. That's especially true for `signrawtransaction`, because you might end up with a partially signed transaction. Worse, if you don't check the errors in the JSON object, you'll just see the `hex` and not realize that it's either unsigned or partially signed. -### 7. Send the Transaction +### 8. Send the Transaction You can now send your transaction, using all of the previous techniques: ``` From 603863da54677e4709f1274132ef415c85d09395 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 13:19:31 +0200 Subject: [PATCH 115/202] Update 15_2_Programming_Bitcoind_with_C.md --- 15_2_Programming_Bitcoind_with_C.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15_2_Programming_Bitcoind_with_C.md b/15_2_Programming_Bitcoind_with_C.md index 2c410a6..8155d2a 100644 --- a/15_2_Programming_Bitcoind_with_C.md +++ b/15_2_Programming_Bitcoind_with_C.md @@ -341,7 +341,7 @@ The entire code, with a _little_ more error-checking appears in the Appendix. ## Summary: Programming Bitcoind with C -Using the techniques outlined in [§12.2](12_2_Accessing_Bitcoind_with_C.md) you can write a much more complex program using C calls. This section offers an example, with the first cut of a program that will send money to an address, without your users worrying about where it's coming from, how much they're paying as a fee, or how they get their change back. Obviously, a real-world program would need much better user-input control and error handling, but by outlining how the RPC code works, this section opens up the programming doorways to allow you to take the next step. +Using the techniques outlined in [§15.1](15_1_Accessing_Bitcoind_with_C.md) you can write a much more complex program using C calls. This section offers an example, with the first cut of a program that will send money to an address, without your users worrying about where it's coming from, how much they're paying as a fee, or how they get their change back. Obviously, a real-world program would need much better user-input control and error handling, but by outlining how the RPC code works, this section opens up the programming doorways to allow you to take the next step. ## Appendix: Sending to an Address From ed53bf1ac0bedfb99fa7cd516abe6e53c3b43ac0 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 13:21:39 +0200 Subject: [PATCH 116/202] Update 15_2_Programming_Bitcoind_with_C.md --- 15_2_Programming_Bitcoind_with_C.md | 1 + 1 file changed, 1 insertion(+) diff --git a/15_2_Programming_Bitcoind_with_C.md b/15_2_Programming_Bitcoind_with_C.md index 8155d2a..a72588c 100644 --- a/15_2_Programming_Bitcoind_with_C.md +++ b/15_2_Programming_Bitcoind_with_C.md @@ -157,6 +157,7 @@ if (!tx_id) { Repeat the standard RPC-lookup methodology to get a new address using get new address method. ``` + rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETNEWADDRESS); lu_response = bitcoinrpc_resp_get (btcresponse); lu_result = json_object_get(lu_response,"result"); char *address = strdup(json_string_value(lu_result)); From 6122b9b356a8d1bc041c2e7dae7e9fcd7b9db4cf Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 13:29:30 +0200 Subject: [PATCH 117/202] 15_2_Programming_Bitcoind_with_C.md --- 15_2_Programming_Bitcoind_with_C.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15_2_Programming_Bitcoind_with_C.md b/15_2_Programming_Bitcoind_with_C.md index a72588c..6e49505 100644 --- a/15_2_Programming_Bitcoind_with_C.md +++ b/15_2_Programming_Bitcoind_with_C.md @@ -512,7 +512,7 @@ int main(int argc, char *argv[]) { /* 5.2 Create the Output Parameters */ - json_t *outputparams = NULL; + json_t *outputparams = NULL; outputparams = json_object(); char tx_amount_string[32]; From 5da470fa203e3e8ee6bd35587ca2d858f7007a4f Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 24 Jun 2020 21:15:10 +0200 Subject: [PATCH 118/202] Add files via upload --- ...3D8DF52A3510C3A8E6AA5DCBDD67C74A547004.asc | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 signed-cla/CLA.javiervargas.703D8DF52A3510C3A8E6AA5DCBDD67C74A547004.asc diff --git a/signed-cla/CLA.javiervargas.703D8DF52A3510C3A8E6AA5DCBDD67C74A547004.asc b/signed-cla/CLA.javiervargas.703D8DF52A3510C3A8E6AA5DCBDD67C74A547004.asc new file mode 100644 index 0000000..06abf99 --- /dev/null +++ b/signed-cla/CLA.javiervargas.703D8DF52A3510C3A8E6AA5DCBDD67C74A547004.asc @@ -0,0 +1,73 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +# Contributor License Agreement + +Version 1.0 + +Name: Javier Vargas + +E-Mail: jevargas@uniandes.edu.co + +Legal Jurisdiction: Madrid, Spain + +Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line + +Date: 06/19/2020 + +## 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----- + +iQGzBAEBCgAdFiEEcD2N9So1EMOo5qpdy91nx0pUcAQFAl7yQ8cACgkQy91nx0pU +cAQnIQwAsIn+KseET6IN9SqwQoj6zpZX8pXCHohxqFt9c87LbPraKgv/TzuyUphI +AMLRt/a4hOng8cUKdD9bsq70eiGHpW/uOd6VUQKMMdvgyr2+FCY0ljqxB2ZkVccN +/sApr0WAlNnfpxaQAYm6ft+FG3rGKEtdwUBzQ0kGShUdt8I0EiHwvevS5x1SNwaT +kruRWy8xoLD7hWQ3OPOqserwtkqK8fIu4PLVtoiBA+qnFpTCoaREjLoEHpX/KKkk +W2r0VxMm2tr+n0+BgLVOAMMSJkhOA6/hlzFXmUIl5WOOeh5AlLlcowGeaQRsCRJL +Sgd3KwOBA7XRFLai72AjSybLnIVn3yhwoHaCPQiVe4Z5qYf0QDYg1W7janYITgMP +s4a2p/4adH/OP5Xkm/8KFzOLCc0Ixjlm8/jHIfm8odIRCcyEiqJYon2ZSBbYiM3N +UPcxE+XrGnSmanK7PEOjrL9D+pLyozcsZc+HZ56CFwoWUn6PNzBUqeLcalAp5f2X +BRGP20HH +=0qBm +-----END PGP SIGNATURE----- From a3160733952e984854f7d25b471fba48b54d7c78 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 10:33:16 +1000 Subject: [PATCH 119/202] Node.js --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 186 ++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 5 deletions(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 80d01fc..47a8a6c 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -67,14 +67,190 @@ $ npm init $ npm install bcrpc ``` -## Manipulate Your Wallet +In this ```myproject``` directory, create a file called ```server.js``` in which the JavaScript code can be executed. Enter the following at the top of the file to connect to your Bitcoin node: -### Look Up Addresses +``` +const RpcAgent = require('bcrpc'); +agent = new RpcAgent({port: 18332, user: 'bitcoinrpc', pass: 'd8340efbcd34e312044c8431c59c792c'}); +``` -### Look Up Funds +Now we can start writing programs in JavaScript that access Bitcoind. You can use the same RPC commands you would usually use via ```bitcoin-cli```, except they need to be in camelCase. For example, ```getblockhash``` would be ```getBlockHash``` instead. + +### Print the Newest Block + +To print the newest block number along with its hash, we can first call ```getBlockCount```, print it, then pass the block number to ```getBlockHash``` and then print the latest hash. Add this code to ```server.js```: + +``` +agent.getBlockCount(function (err, blockCount) { + if (err) + throw Error(JSON.stringify(err)); + console.log(blockCount.result); + agent.getBlockHash(blockCount.result, function (err, hash) { + if (err) + throw Error(JSON.stringify(err)); + console.log(hash.result); + }) +}); +``` + +You can run it with ```$ node server.js```. You should get an output similar to this: + +``` +1773373 +0000000000000083d29c524d4cfc257adfab8fa9b6f0d207d1d0f1b63e1de11e +``` + +## Look Up Your Wallet + +You can also lookup your wallet and view your balance, transaction count et cetera: + +``` +agent.getWalletInfo(function (err, walletInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(walletInfo.result); +}); +``` + +When you run it, you should get an output similar to this: + +``` +{ + walletname: '', + walletversion: 169900, + balance: 0.0011, + unconfirmed_balance: 0, + immature_balance: 0, + txcount: 2, + keypoololdest: 1591844503, + keypoolsize: 999, + keypoolsize_hd_internal: 1000, + paytxfee: 0, + hdseedid: '6b9ccb7d96c45a3ca407a3f3b0e9b42501f05c49', + private_keys_enabled: true +} +``` + +Instead of printing all the details associated with your wallet, you can print specific information such as your balance. Since a JSON object is being accessed, this can be done by changing the line ```console.log(walletInfo.result);``` to ```console.log(walletInfo.result.balance);```: + +``` +0.0011 +``` ### Create an Address -## Create a Transaction - +We can pass additional arguments to RPC commands as well. Here is an example for generating a new legacy address, with the ```-addresstype``` flag. + +``` +agent.getNewAddress('-addresstype', 'legacy', function (err, newAddress) { + if (err) + throw Error(JSON.stringify(err)); + console.log(newAddress.result); +}); +``` + +Output: +``` +mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ +``` + +### List transactions + +We can list our previous transactions and view information about transactions such as amount and number of confirmations: + +``` +agent.listTransactions(function (err, transactions) { + if (err) + throw Error(JSON.stringify(err)); + console.log(transactions.result); +}); +``` + +We can also examine a transaction based on its txid: + +``` +agent.getTransaction('1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', function (err, transaction) { + if (err) + throw Error(JSON.stringify(err)); + console.log(transaction.result); +}); +``` + +You should get an output similar to this: + +``` +{ + amount: 0.001, + confirmations: 4776, + blockhash: '000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a', + blockindex: 117, + blocktime: 1591857418, + txid: '1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', + walletconflicts: [], + time: 1591857343, + timereceived: 1591857343, + 'bip125-replaceable': 'no', + details: [ + { + address: 'mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', + category: 'receive', + amount: 0.001, + label: '', + vout: 0 + } + ], + hex: '02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00' +} +``` + +### Get address balance + +A useful function when accepting Bitcoin is checking the balance of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with ```getNewAddress``` function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +By default this functions checks the transactions that have been confirmed once, however we can increase this to a higher number such as 6: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +Output: + +``` +0.0011 +``` + +## Sending coins + +We can send coins to an address using the ```sendToAddress``` function: + +``` +agent.sendToAddress('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 0.00001, function(err, txid) { + if (err) + throw Error(JSON.stringify(err)); + console.log(txid.result); +}); +``` + +This should print the txid of the transaction: + +``` +6172d60d154cd4bbb5b6adeaffa191866f3904dd3f525c7a079154aea906b723 +``` + +We can also use the ```getTransaction``` function to view how many confirmations it has, what fee we paid, et cetera. + ## Summary: Accessing Bitcoind with Node + +With BCRPC we can do all the commands available through ```bitcoin-cli```, in JavaScript. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins. From 1f7436fc13ff3288b115d5c51ba2746a727d35c9 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 10:34:17 +1000 Subject: [PATCH 120/202] Node.js --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 47a8a6c..0926ce4 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -1,7 +1,5 @@ # 18.3: Accessing Bitcoind with NodeJS -> **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. - ## Set Up Node.js BCRPC is built on node.js. Thus, you'll first need to install the `node.js` and `npm` (node package manager) packages for your system. From b49fc22895dcac749f49e9222fe7914ff6e168e3 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 14:12:50 +1000 Subject: [PATCH 121/202] Go --- 18_1_Accessing_Bitcoind_with_Go.md | 337 +++++++++++++++++++++++++ 18_3_Accessing_Bitcoind_with_NodeJS.md | 4 +- README.md | 4 +- 3 files changed, 341 insertions(+), 4 deletions(-) create mode 100644 18_1_Accessing_Bitcoind_with_Go.md diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md new file mode 100644 index 0000000..0ab73e1 --- /dev/null +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -0,0 +1,337 @@ +# 18.1: Accessing Bitcoind with NodeJS + +## Set up Go + +First, install curl if you haven't already: + +``` +$ sudo apt install curl +``` + +Then, look at the [Go downloads page](https://golang.org/dl/) and get the link for the latest download: + +``` +$ curl -O https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz +``` + +Once it finishes downloading, compare the hash of the download to the hash on the [Go downloads page](https://golang.org/dl/): + +``` +$ sha256sum go1.14.4.linux-amd64.tar.gz +aed845e4185a0b2a3c3d5e1d0a35491702c55889192bb9c30e67a3de6849c067 /home/user1/go1.14.4.linux-amd64.tar.gz +``` + +The hashes should match. Now we can extract the tarball and install Go on our system: + +``` +$ tar xvf go1.12.5.linux-amd64.tar.gz +$ sudo chown -R root:root ./go +$ sudo mv go /usr/local +``` + +Now we need to create a Go path to specify our environment. Open the ```~/.profile``` file with an editor of your choice and add the following to the end of it: + +``` +export GOPATH=$HOME/work +export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin +``` + +Then, refresh your profile: + +``` +$ source ~/.profile +``` + +Lastly, create the directory for your Go workspace: + +``` +$ mkdir $HOME/work +``` + +## Setup btcd rpcclient + +We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. We can use ```go get``` to download it: + +``` +$ go get github.com/btcsuite/btcd/rpcclient +``` + +To test that it works, navigate to the directory with the Bitcoin core examples: + +``` +$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +``` + +Modify the ```main.go``` file and enter the details associated with your Bitcoin core setup: + +``` + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "d8340efbcd34e312044c8431c59c792c", +``` + +Now run: + +``` +$ go run main.go +``` + +You should see the block count printed: + +``` +2020/06/24 20:41:01 Block count: 1773552 +``` + +### Print the latest block + +Leave the btcd directory and create a new Go project: + +``` +$ mkdir -p ~/work/src/myproject/bitcoin +$ cd ~/work/src/myproject/bitcoin +``` + +In this directory, create a file called ```main.go``` and enter the following in it: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatal(err) + } + blockHash, err := client.GetBlockHash(blockCount) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%d\n", blockCount) + fmt.Printf("%s\n", blockHash.String()) +} +``` + +Make sure to change your username and password to those from your ```~/.bitcoin/bitcoin.conf``` file. When you run this: + +``` +$ go run main.go +1773561 +00000000000000346bab4126f418a5820692c9a7de7ef79717bebfccebacad61 +``` + +The latest block number along with its hash should be printed out. + +### Getting your wallet balance + +Since the btcd rpcclient is quite limited, we can't make a use the ```getwalletinfo``` functino, however we can get the balance of our wallet: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + wallet, err := client.GetBalance("*") + if err != nil { + log.Fatal(err) + } + fmt.Println(wallet) +} +``` + +You should get an output similar to this: + +``` +0.000689 BTC +``` + +### Get amount received by an address + +We can retrieve the amount of Bitcoin received by a specific address: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", defaultNet) + if err != nil { + log.Fatal(err) + } + wallet, err := client.GetReceivedByAddress(addr) + + fmt.Println(wallet) +} +``` + +The defaultNet variable is used to specify whether our Bitcoin node is on testnet or on mainnet. + +### Sending Bitcoin to an address + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", defaultNet) + if err != nil { + log.Fatal(err) + } + + sent, err := client.SendToAddress(addr, btcutil.Amount(1e4)) + if err != nil { + log.Fatal(err) + } + fmt.Println(sent) +} +``` + +This outputs the txid of the transaction. + +### Lookup a transaction + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg/chainhash" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + chash, err := chainhash.NewHashFromStr("1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df") + if err != nil { + log.Fatal(err) + } + transactions, err := client.GetTransaction(chash) + if err != nil { + log.Fatal(err) + } + fmt.Println(transactions) +} +``` + +This prints out the details associated with a transaction, such as its amount and how many times it has been confirmed: + +``` +{ + "amount": 0.00100000, + "confirmations": 4817, + "blockhash": "000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a", + "blockindex": 117, + "blocktime": 1591857418, + "txid": "1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df", + "walletconflicts": [ + ], + "time": 1591857343, + "timereceived": 1591857343, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", + "category": "receive", + "amount": 0.00100000, + "label": "", + "vout": 0 + } + ], + "hex": "02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00" +} +``` + +## Summary: Accessing Bitcoind with Node + +Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. \ No newline at end of file diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 0926ce4..a133071 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -201,9 +201,9 @@ You should get an output similar to this: } ``` -### Get address balance +### Get Amount Received by an Address -A useful function when accepting Bitcoin is checking the balance of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with ```getNewAddress``` function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received: +A useful function when accepting Bitcoin is checking the received Bitcoin of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with ```getNewAddress``` function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received: ``` agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { diff --git a/README.md b/README.md index bd6f387..2b7f575 100644 --- a/README.md +++ b/README.md @@ -104,9 +104,9 @@ _This section is currently a messy set of older writings which are being reorgan * 17.4: Integrating Libwally and Scripts * 17.0: Talking to Lightningd with C * 18.0: Talking to Bitcoind with Other Languages - * [18.1: Accessing Bitcoind with Go] + * [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) — Needs Rewrite + Editing - * [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) — Needs Rewrite + Editing + * [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) * [18.4: Accessing Bitcoind with Python] * [18.5: Accessing Bitcoind with Rust] * [18.6: Accessing Bitcoind with Swift] From 3c14e11745dd85031d656d9ea0d17a38827c4902 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 14:15:56 +1000 Subject: [PATCH 122/202] go --- 18_1_Accessing_Bitcoind_with_Go.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 0ab73e1..d4341ae 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -1,4 +1,4 @@ -# 18.1: Accessing Bitcoind with NodeJS +# 18.1: Accessing Bitcoind with Go ## Set up Go @@ -334,4 +334,4 @@ This prints out the details associated with a transaction, such as its amount an ## Summary: Accessing Bitcoind with Node -Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. \ No newline at end of file +Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. From e2c42668ae1297fd4bdda960a7daf73c50db4db7 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Fri, 26 Jun 2020 17:05:47 +0200 Subject: [PATCH 123/202] Create 15_3_Receiving_Bitcoind_Notifications_with_C.md --- ...Receiving_Bitcoind_Notifications_with_C.md | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/15_3_Receiving_Bitcoind_Notifications_with_C.md b/15_3_Receiving_Bitcoind_Notifications_with_C.md new file mode 100644 index 0000000..4db5ec8 --- /dev/null +++ b/15_3_Receiving_Bitcoind_Notifications_with_C.md @@ -0,0 +1,196 @@ +# 15.3 Receiving Bitcoind Notifications with C + +> **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. + +[§15.3](15_3_Receiving_Bitcoind_Notifications_with_C.md) In this chapter we will show how to create a simple listener for bitcoin blockchain to receive notifications using ZMQ-based (http://zeromq.org/) notification interface, which is a highly scalable networking library written in C that acts like a concurrency framework. Bitcoin allows connection points where clients can subscribe to get notified about blockchain events like raw transactions or raw blocks. + +## Install ZMQ + +To create a blockchain listener in C you need to install ZMQ following this steps. + + 1. Install ZMQ + 2. Create C program. + 3. Compile C program. + 4. Configure bitcoind to allow ZMQ notifications + 5. Execute listener. + +### 1. Install ZMQ + +``` +sudo apt-get install libzmq3-dev +``` +Output + +``` +Reading package lists... Done +Building dependency tree +Reading state information... Done +The following NEW packages will be installed: + libzmq3-dev +0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded. +Need to get 400 kB of archives. +After this operation, 2.227 kB of additional disk space will be used. +Get:1 http://es.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 libzmq3-dev amd64 4.2.5-1ubuntu0.2 [400 kB] +Fetched 400 kB in 0s (1.114 kB/s) +Selecting previously unselected package libzmq3-dev:amd64. +(Reading database ... 313982 files and directories currently installed.) +Preparing to unpack .../libzmq3-dev_4.2.5-1ubuntu0.2_amd64.deb ... +Unpacking libzmq3-dev:amd64 (4.2.5-1ubuntu0.2) ... +Setting up libzmq3-dev:amd64 (4.2.5-1ubuntu0.2) ... +Processing triggers for man-db (2.8.3-2ubuntu0.1) ... +``` +Then + +``` +sudo apt-get install libczmq-dev +``` +Output: + +``` +Reading package lists... Done +Building dependency tree +Reading state information... Done +The following additional packages will be installed: + libczmq4 +The following NEW packages will be installed: + libczmq-dev libczmq4 +0 upgraded, 2 newly installed, 0 to remove and 18 not upgraded. +Need to get 496 kB of archives. +After this operation, 2.148 kB of additional disk space will be used. +Do you want to continue? [Y/n] y +Get:1 http://es.archive.ubuntu.com/ubuntu bionic/universe amd64 libczmq4 amd64 4.1.0-2 [145 kB] +Get:2 http://es.archive.ubuntu.com/ubuntu bionic/universe amd64 libczmq-dev amd64 4.1.0-2 [351 kB] +Fetched 496 kB in 0s (1.287 kB/s) +Selecting previously unselected package libczmq4:amd64. +(Reading database ... 314055 files and directories currently installed.) +Preparing to unpack .../libczmq4_4.1.0-2_amd64.deb ... +Unpacking libczmq4:amd64 (4.1.0-2) ... +Selecting previously unselected package libczmq-dev:amd64. +Preparing to unpack .../libczmq-dev_4.1.0-2_amd64.deb ... +Unpacking libczmq-dev:amd64 (4.1.0-2) ... +Setting up libczmq4:amd64 (4.1.0-2) ... +Setting up libczmq-dev:amd64 (4.1.0-2) ... +Processing triggers for man-db (2.8.3-2ubuntu0.1) ... +Processing triggers for libc-bin (2.27-3ubuntu1) ... +``` + +### 2. Create C Program + +Now we've installed ZMQ and we can compile our C program using it's notifications. +The program use czmq.h library and receives two parameters as follows, first param is the point exposed by bitcoind and second the topic about we'll listen. + +``` c +#include +int main(int argc, char ** argv) { + + char *zmqserver; + char *topic; + + if (argc < 3) { + printf("\nUSAGE:\nchainlistener \n\n"); + return 0; + } else { + zmqserver = argv[1]; + topic = argv[2]; + } + + zsock_t *socket = zsock_new_sub(zmqserver, topic); + assert(socket); + + while(1) { + zmsg_t *msg; + int rc = zsock_recv(socket, "m", &msg); + assert(rc == 0); + + char *header = zmsg_popstr(msg); + zframe_t *zdata = zmsg_pop(msg); + unsigned int *no = (unsigned int*)zmsg_popstr(msg); + + char *data = zframe_strhex(zdata); + int len = zframe_size(zdata); + printf("Size: %d\n", len); + printf("Data: %s", data); + printf("\nNo: %d\n", *no); + + free(header); + free(data); + free(no); + free(zdata); + zmsg_destroy(&msg); + sleep(1); + } + zsock_destroy(&socket); + return 0; +} +``` + +### 3. Compile C program + +To compile this C program you have to do it with clang or gcc compiler and test zmq and czmq libraries. + +``` +gcc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq +``` + +### 4. Configure ZMQ on bitcoind + +Add this lines to bitcoin.conf file and restart daemon. + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` +Then test it's working using this command + +``` +$ bitcoin-cli --testnet getzmqnotifications +``` +Output: +``` +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` +### 5. Execute listener: + +``` +$ ./chainlistener tcp://127.0.0.1:28333 rawtx +Size: 250 +Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 +No: 67 +Size: 249 +Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 +No: 68 +Size: 250 +Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 +No: 69 +Size: 250 +Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 +No: 70 +....... +``` + + +### For More Information + +In this repository you can browse find more details about ZMQ notifications and others kind of messages. (https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md) + +### Summary Receiving Bitcoind Notifications with C.md + +By using ZMQ framework, you can easily receive notifications by subscribing to a connection point exposed by bitcoind changing configuration file. + + + + + + + From 785eb9b6b0429b26068e4dddcde915f9a4afaa63 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Fri, 26 Jun 2020 19:05:03 +0200 Subject: [PATCH 124/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index 864a2e4..1528fb4 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -4,6 +4,6 @@ _This is currently a placeholder; Writing it in Task #15 on the current [TODO li This section will talk about using the Tor services that are now available courtesy of Bitcoin Standup._) - * 12.1: Verifying Your Tor Setup + * [12.1: Verifying Your Tor Setup](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/12_1_Verifying_Your_Tor_Setup) * 12.2: Changing Your Bitcoin Hidden Services * 12.3: Adding SSH Hiddne Services From aa551bed03eabce23887060d8d26ebd430e364b6 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Fri, 26 Jun 2020 22:21:49 +0200 Subject: [PATCH 125/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index 1528fb4..8d2c560 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -4,6 +4,6 @@ _This is currently a placeholder; Writing it in Task #15 on the current [TODO li This section will talk about using the Tor services that are now available courtesy of Bitcoin Standup._) - * [12.1: Verifying Your Tor Setup](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/12_1_Verifying_Your_Tor_Setup) + * [12.1: Verifying Your Tor Setup](12_1_Verifying_Your_Tor_Setup) * 12.2: Changing Your Bitcoin Hidden Services * 12.3: Adding SSH Hiddne Services From a3df9f260b9b31d546f6a3e80c5cec40cae9b274 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Fri, 26 Jun 2020 22:23:00 +0200 Subject: [PATCH 126/202] Create 12_1_Verifying_Your_Tor_Setup.md --- 12_1_Verifying_Your_Tor_Setup.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 12_1_Verifying_Your_Tor_Setup.md diff --git a/12_1_Verifying_Your_Tor_Setup.md b/12_1_Verifying_Your_Tor_Setup.md new file mode 100644 index 0000000..b253e13 --- /dev/null +++ b/12_1_Verifying_Your_Tor_Setup.md @@ -0,0 +1,18 @@ +# Chapter 12: Verifying Your Tor Setup + +In this chapter we will verify tor installation and setup. + +``` +~$ sudo -u debian-tor tor --verify-config +``` + +If tor is installed correctly you should see an output like this: + +``` +Jun 26 21:52:09.230 [notice] Tor 0.4.3.5 running on Linux with Libevent 2.0.21-stable, OpenSSL 1.0.2n, Zlib 1.2.11, Liblzma 5.2.2, and Libzstd N/A. +Jun 26 21:52:09.230 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning +Jun 26 21:52:09.230 [notice] Read configuration file "/etc/tor/torrc". +Configuration was valid + +~$ +``` From d938af4e91f187c2782c0ec84fef06e6d3a7057d Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Fri, 26 Jun 2020 22:24:06 +0200 Subject: [PATCH 127/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index 8d2c560..eb09b60 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -4,6 +4,6 @@ _This is currently a placeholder; Writing it in Task #15 on the current [TODO li This section will talk about using the Tor services that are now available courtesy of Bitcoin Standup._) - * [12.1: Verifying Your Tor Setup](12_1_Verifying_Your_Tor_Setup) + * [12.1: Verifying Your Tor Setup](https://github.com/javiervargas/Learning-Bitcoin-from-the-Command-Line/blob/master/12_1_Verifying_Your_Tor_Setup.md) * 12.2: Changing Your Bitcoin Hidden Services * 12.3: Adding SSH Hiddne Services From 19826bd0e64b45a0c0b22f2a5f8eeae2db4cbb18 Mon Sep 17 00:00:00 2001 From: gorazdko Date: Sat, 27 Jun 2020 17:01:38 +0200 Subject: [PATCH 128/202] add signed CLA --- ...F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 signed-cla/CLA.gorazdko.41F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc diff --git a/signed-cla/CLA.gorazdko.41F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc b/signed-cla/CLA.gorazdko.41F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc new file mode 100644 index 0000000..dd92c3d --- /dev/null +++ b/signed-cla/CLA.gorazdko.41F0EA1699A74C1E2FA41B538CF96BC3FF9DBBCE.asc @@ -0,0 +1,74 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +# Contributor License Agreement + +Version 1.0 + +Name: Gorazd Kovacic + +E-Mail: gorazdko@gmail.com + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line + +Date: 06-27-2020 + +## 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----- + +iQIzBAEBCgAdFiEEQfDqFpmnTB4vpBtTjPlrw/+du84FAl73XO4ACgkQjPlrw/+d +u84JUg//TT6ySwiHIjl+gZiIZQjiNIpPqrpeb8pmJvoL1+CkJgidPR03pMbuz5XT +TGczVIreLa9jf3K96Sj/0uRcTi5mZWE6pfAZT6hTVPiajHPri14oDrXB0Yar1btx +Oq+3b+ryb6BOfXKub4Kl1JP8PyUanBD/1/j4jRAZcxOjHOEUdw5gJYH3VpKm3+ds +RaMABUmpPd6dOCrfGojbAeajcWSP1KpX2zxDYxJvnYZ8f3spl2mVb8ajqHt7T3FK +Kff2YQBT3HE3Ln81bu2SbhE7E5X5BWasNe1oH73jS9T2CsXkretg68lVUR2Cw7C2 +uHtbn8zA2ySntb6xyInHHA7uhBNRtnxwm9QSRgq/PisuIqA9qMnhDSSSVXopi6FE +iF4Zf5NOq0l2ZIJQpNEOXG7WnMpqaXr7GYqq47PBaY80H+UdnLyVmJxattPDSV5e +tiBUF3862PWeDxsIe3jbce4N8SPstcqgnTGiSTcNft7WzhW6pxDhYDaNa/oqJ3bk +zAkX6LAG1MhNsGnnOZ75e9hEjFZg7grVmjwRbyo+2PgNy1e0+UNTCndCM7q3fhjO +AE3hNB+YGQGiXJmD5oh4zFVeJldIkRBjOdagOmvrQizJsWpgh9xD0jEfL5dxcq9c +/1InfBONgGnEwXSengCHVVEOIJeB/VPxd1y6O3240szyJxYe6p0= +=UKxv +-----END PGP SIGNATURE----- From 18dfdb87aa1f0dbca6a4b6b060f1ed349364b802 Mon Sep 17 00:00:00 2001 From: gorazdko Date: Sat, 27 Jun 2020 17:03:17 +0200 Subject: [PATCH 129/202] add Rust section: Accessing bitcoind with Rust --- 18_5_Accessing_Bitcoind_with_Rust.md | 395 +++++++++++++++++++++++++++ README.md | 3 +- 2 files changed, 396 insertions(+), 2 deletions(-) create mode 100644 18_5_Accessing_Bitcoind_with_Rust.md diff --git a/18_5_Accessing_Bitcoind_with_Rust.md b/18_5_Accessing_Bitcoind_with_Rust.md new file mode 100644 index 0000000..eaa9d1b --- /dev/null +++ b/18_5_Accessing_Bitcoind_with_Rust.md @@ -0,0 +1,395 @@ +# 18.5: Accessing Bitcoind with Rust + +## Setup + +We'll need `Rust` and `Cargo`. Installing them is easy: + +```vim +$ curl https://sh.rustup.rs -sSf | sh +``` + +If everything goes well, we should see: + +```vim +Rust is installed now. Great! +``` + +To set `Bitcoin Regtest` network up and allow communication with our Rust program we +will be using the following `bitcoind` configuration in `bitcoin.conf` + +```vim +regtest=1 +server=1 +rpcuser=bitcoin +rpcpassword=password +[test] +rpcport=18443 +``` + +> Note: Never use a simple password like that when on Bitcoin Mainnet! + +### Create a New Project + +We create a new project with `cargo new btc_test`: + +```vim +gorazd@gorazd-MS-7C37:~/Projects/BlockchainCommons$ cargo new btc_test + Created binary (application) `btc_test` package +``` + +Let's move into the newly created project `btc_test`. We notice a "hello world" example +with the source code in `src/main.rs` and a `Cargo.toml` file. Let's run it with `cargo run`: + +```vim +gorazd@gorazd-MS-7C37:~/Projects/BlockchainCommons/btc_test$ cargo run + Compiling btc_test v0.1.0 (/home/gorazd/Projects/BlockchainCommons/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 0.14s + Running `target/debug/btc_test` +Hello, world! +``` + +> Note: if you run into error “linker ‘cc’ not found”, you'll have to install a +C compiler. If on Linux, go ahead and install the [development tools](https://www.ostechnix.com/install-development-tools-linux/). + + +We will use `bitcoincore-rpc` crate (library), therefore we add it to our `Cargo.toml` +under section `dependencies` like so: + +```rust +[dependencies] +bitcoincore-rpc = "0.11.0" +``` + +Running our example again will install our crate and +its dependencies. + +```vim +gorazd@gorazd-MS-7C37:~/Projects/BlockchainCommons/btc_test$ cargo run + Updating crates.io index + ... + Compiling bitcoin v0.23.0 + Compiling bitcoincore-rpc-json v0.11.0 + Compiling bitcoincore-rpc v0.11.0 + Compiling btc_test v0.1.0 (/home/gorazd/Projects/BlockchainCommons/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 23.56s + Running `target/debug/btc_test` +Hello, world! +``` + +## Build Your Connection + +Let us create a Bitcoin `RPC client` and modify the `main.rs`: + +```rust +use bitcoincore_rpc::{Auth, Client}; + +fn main() { + let rpc = Client::new( + "http://localhost:18443".to_string(), + Auth::UserPass("bitcoin".to_string(), "password".to_string()), + ) + .unwrap(); +} +``` + +`Cargo run` should successfully compile and run the example with one warning +`warning: unused variable: rpc` + + +### Make an RPC Call + +This is a simple RPC call without arguments: + +```rust +let mining_info = rpc.get_mining_info().unwrap(); +println!("{:#?}", mining_info); +``` + +The compiler will tell us to include traits into scope. So lets add them: + +```rust +use bitcoincore_rpc::{Auth, Client, RpcApi}; +``` + +If our properly configured `bitcoind` is running, executing our example should +result in: + +```vim +gorazd@gorazd-MS-7C37:~/Projects/BlockchainCommons/btc_test$ cargo run + Compiling btc_test v0.1.0 (/home/gorazd/Projects/BlockchainCommons/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 0.80s + Running `target/debug/btc_test` +GetMiningInfoResult { + blocks: 5167, + current_block_weight: Some( + 0, + ), + current_block_tx: Some( + 0, + ), + difficulty: 0.00000000046565423739069247, + network_hash_ps: 1.764705882352941, + pooled_tx: 2, + chain: "regtest", + warnings: "", +} +``` + +If we wanted we could close the connection: + +```rust + let _ = rpc.stop().unwrap(); +``` + + +## Manipulate Your Wallet + +### Look Up Addresses + +Here we will make our first call with an argument. To see the type of an argument, +we want to look at the function definition: + +```rust +fn get_address_info(&self, address: &Address) -> Result { +self.call("getaddressinfo", &[address.to_string().into()]) +} +``` + +We see that our argument is of type `Address` and that it will be borrowed. Further, +looking at the structure `Address`, we notice a convenient `trait` implemented which +allows us to create an `Address` out of a string: + +```rust +impl FromStr for Address { + type Err = Error; + + fn from_str(s: &str) -> Result { +``` + +Now that we now what structure and trait we are dealing with, we bring them into +scope + +```rust +use bitcoincore_rpc::bitcoin::Address; +use std::str::FromStr; +``` + +so we can use them: + +```rust +let addr = Address::from_str("bcrt1qanga5jxx845q82h9qgjfuedps92lktqv073qct").unwrap(); +let addr_info = rpc.get_address_info(&addr).unwrap(); +println!("{:?}", addr_info); +``` + +Running our program results in: + +```vim +GetAddressInfoResult { address: bcrt1qanga5jxx845q82h9qgjfuedps92lktqv073qct, script_pub_key: Script(OP_0 OP_PUSHBYTES_20 ecd1da48c63d6803aae502249e65a18155fb2c0c), is_mine: Some(true), is_watchonly: Some(false), is_script: Some(false), is_witness: Some(true), witness_version: Some(0), witness_program: Some([236, 209, 218, 72, 198, 61, 104, 3, 170, 229, 2, 36, 158, 101, 161, 129, 85, 251, 44, 12]), script: None, hex: None, pubkeys: None, n_signatures_required: None, pubkey: Some(PublicKey { compressed: true, key: PublicKey(f895d610ab1ceddfd87814b1f7a911fee1135a9347d4fd1754a06ddf84757c5c527a90804949b025d7272bef4d58a1324c18d7a8f6b7ffa949447bcb6a225e6e) }), embedded: None, is_compressed: None, label: "lbl", timestamp: Some(1582063890), hd_key_path: Some(m/0'/0'/99'), hd_seed_id: Some(00b332a133c03c4e613f0106dc814bcc79af60ff), labels: [GetAddressInfoResultLabel { name: "lbl", purpose: Receive }] } +``` + +> Note: this call doesn't work with recent versions of Bitcoin Core due to the +crate not addressing the latest API changes in Bitcoin Core. +We expect it to be solved in the next crate's release. + +### Look Up Funds + +We can look up our funds without optional arguments like so: + +```rust +let balance = rpc.get_balance(None, None).unwrap(); +println!("Balance: {:?} BTC", balance.as_btc()); +``` + +```vim +Balance: 3433.71692741 BTC +``` + +### Create an Address + +Here is an example of calling an RPC method with the optional arguments specified, i.e. +a label and an address type: + +```rust +// Generate a new address +let myaddress = rpc + .get_new_address(Option::Some("BlockchainCommons"), Option::Some(json::AddressType::Bech32)) + .unwrap(); +println!("address: {:?}", myaddress); +``` + +If we have inspected our function's definition we bring the missing things into +scope. Otherwise the compiler will hint us to do so: + +```rust +use bitcoincore_rpc::{json, Auth, Client, RpcApi}; +``` + +Program execution results in: + +```vim +address: bcrt1q0y0dk70lut5l3y4f0fe52am23egfmr63dejy9r +``` + +Now, we would like to have some bitcoins to our newly generated address. Since +we are on the `Regtest` network we can generate them ourselves: + +```rust +// Generate 101 blocks to our address +let _ = rpc.generate_to_address(101, &myaddress); +``` + +## Create a Transaction + +First, we list unspent transactions. Let's look at those with at least 3 BTC and take the first one: + +```rust +let unspent = rpc +.list_unspent( + None, + None, + None, + None, + Option::Some(json::ListUnspentQueryOptions { + minimum_amount: Option::Some(Amount::from_btc(3.0).unwrap()), + maximum_amount: None, + maximum_count: None, + minimum_sum_amount: None, + }), +) +.unwrap(); + +let selected_tx = &unspent[0]; + +println!("selected unspent transaction: {:#?}", selected_tx); +``` +Here it is: + +```vim +selected unspent transaction: ListUnspentResultEntry { + txid: 34e283eb5b52c66aba9766bdda46eb038bc1138e992b593c22f7cbf1d2e9ba10, + vout: 0, + address: Some( + bcrt1q7lju6c0ynwerch0te4saxwxgm70ltd3lr9vj6l, + ), + label: Some( + "", + ), + redeem_script: None, + witness_script: None, + script_pub_key: Script(OP_0 OP_PUSHBYTES_20 f7e5cd61e49bb23c5debcd61d338c8df9ff5b63f), + amount: Amount(625000000 satoshi), + confirmations: 4691, + spendable: true, + solvable: true, + descriptor: None, + safe: true, +} +``` + +This will require to bring another structure into scope: + +```rust +use bitcoincore_rpc::bitcoin::{Address, Amount}; +``` + +We can now populate some variables: the available amount and +the utxo, the recipient's address and the amount we want to send. + +```rust +let unspent_amount = selected_tx.amount; + +let selected_utxos = json::CreateRawTransactionInput { +txid: selected_tx.txid, +vout: selected_tx.vout, +sequence: None, +}; + +let recipient = Address::from_str("bcrt1q6rhpng9evdsfnn833a4f4vej0asu6dk5srld6x").unwrap(); +println!("recipient: {:?}", recipient); + +// send all bitcoin in the UTXO except a minor value which will be paid to miners +let amount = unspent_amount - Amount::from_btc(0.00001).unwrap(); + +let mut output = HashMap::new(); +output.insert( +"bcrt1q6rhpng9evdsfnn833a4f4vej0asu6dk5srld6x".to_string(), +amount, +); +``` + +Another trait is necessary for the output variable: HashMap. It allows us to store +values by key which we need to represent `{address : amount}` information. + +```rust +use std::collections::HashMap; +``` + +We are ready to create a raw transaction: + +```rust +let unsigned_tx = rpc +.create_raw_transaction(&[selected_utxos], &output, None, None) +.unwrap(); + +println!("unsigned tx {:#?}", unsigned_tx); +``` + +Here it is: + +```vim +unsigned tx Transaction { + version: 2, + lock_time: 0, + input: [ + TxIn { + previous_output: OutPoint { + txid: 34e283eb5b52c66aba9766bdda46eb038bc1138e992b593c22f7cbf1d2e9ba10, + vout: 0, + }, + script_sig: Script(), + sequence: 4294967295, + witness: [], + }, + ], + output: [ + TxOut { + value: 624999000, + script_pubkey: Script(OP_0 OP_PUSHBYTES_20 d0ee19a0b9636099ccf18f6a9ab3327f61cd36d4), + }, + ], +} +``` + +Finally, we can sign and broadcast our transaction: + +```rust +// sign transaction +let signed_tx = rpc +.sign_raw_transaction_with_wallet(&unsigned_tx, None, None) +.unwrap(); + +println!("singed tx {:?}", signed_tx.transaction().unwrap()); + +// broadcast transaction +let txid_sent = rpc +.send_raw_transaction(&signed_tx.transaction().unwrap()) +.unwrap(); + +println!("{:?}", txid_sent); +``` + +```vim +singed tx Transaction { version: 2, lock_time: 0, input: [TxIn { previous_output: OutPoint { txid: 34e283eb5b52c66aba9766bdda46eb038bc1138e992b593c22f7cbf1d2e9ba10, vout: 0 }, script_sig: Script(), sequence: 4294967295, witness: [[48, 68, 2, 32, 85, 113, 140, 197, 142, 140, 122, 26, 174, 71, 94, 152, 76, 104, 5, 111, 113, 192, 179, 1, 58, 6, 27, 141, 18, 50, 217, 53, 154, 26, 5, 98, 2, 32, 53, 148, 139, 57, 234, 151, 71, 149, 134, 202, 160, 136, 15, 144, 103, 232, 134, 37, 136, 184, 117, 159, 235, 92, 59, 102, 197, 213, 67, 64, 89, 207, 1], [3, 4, 197, 157, 36, 136, 177, 169, 182, 219, 121, 187, 251, 153, 207, 165, 173, 117, 142, 93, 181, 107, 185, 97, 10, 168, 210, 148, 67, 127, 246, 229, 12]] }], output: [TxOut { value: 624999000, script_pubkey: Script(OP_0 OP_PUSHBYTES_20 d0ee19a0b9636099ccf18f6a9ab3327f61cd36d4) }] } +5d2f1b7c6fc29967d820532c46200b35f62b6e6f8da614ae86922c20167f6d0e +``` + +## For More Information + +You can now mine a block and try to see for yourself if the last transaction is really in the block. +If you need help look at the crate's [documentation](https://crates.io/crates/bitcoincore-rpc) or run some tests in its [repository](https://github.com/rust-bitcoin/rust-bitcoincore-rpc). + +## Summary + +We have shown how to access `bitcoind` in `Rust` and send a transaction +on the `Bitcoin Regtest Network` explaining all the steps required. diff --git a/README.md b/README.md index b5d5dec..4cd4438 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ _This tutorial assumes that you have some minimal background of how to use the c * [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) — Needs Rewrite + Editing * [18.4: Accessing Bitcoind with Python](18_4_Accessing_Bitcoind_with_Python.md) - * [18.5: Accessing Bitcoind with Rust] — Unwritten + * [18.5: Accessing Bitcoind with Rust](18_5_Accessing_Bitcoind_with_Rust.md) * [18.6: Accessing Bitcoind with Swift] — Unwritten ### APPENDICES @@ -200,4 +200,3 @@ The following keys may be used to communicate sensitive information to developer | Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | You can import a key by running the following command with that individual’s fingerprint: `gpg --recv-keys ""` Ensure that you put quotes around fingerprints that contain spaces. - From e5a3882af7d23bce7cb12b002f7dc7fb4ed8f46c Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 30 Jun 2020 22:33:36 +0200 Subject: [PATCH 130/202] Create 12_2_Changing_Your_Bitcoin_Hidden_Services.md --- 12_2_Changing_Your_Bitcoin_Hidden_Services.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 12_2_Changing_Your_Bitcoin_Hidden_Services.md diff --git a/12_2_Changing_Your_Bitcoin_Hidden_Services.md b/12_2_Changing_Your_Bitcoin_Hidden_Services.md new file mode 100644 index 0000000..a882878 --- /dev/null +++ b/12_2_Changing_Your_Bitcoin_Hidden_Services.md @@ -0,0 +1,18 @@ +# Chapter 12.2: Changing Your Bitcoin Hidden Services + +In this chapter we will show you how to create or change your local Bitcoin Hidden Service. To archieve this we need to add current user to tor or debian-tor group to guarantee that Bitcoin daemon can sets up an automatic hidden service on the first startup if it's correclty configured. Bitcoind will create a file called onion_private_key in the data directory. Further check if file control.authcookie exists like this: + +``` +~$ ll /run/tor/control.authcookie +-rw-r----- 1 debian-tor debian-tor 32 jun 26 09:44 /run/tor/control.authcookie +``` + +Add your user to debian-tor group like this: + +``` +~$ sudo usermod -a -G debian-tor [CHANGE_MY_USER] +``` + + + ll /run/tor/control.authcookie +-rw-r----- 1 debian-tor debian-tor 32 jun 26 09:44 /run/tor/control.authcookie From 0f7543aaa367db94119f0baf3af8370934ae434e Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 30 Jun 2020 23:07:03 +0200 Subject: [PATCH 131/202] Update 12_1_Verifying_Your_Tor_Setup.md --- 12_1_Verifying_Your_Tor_Setup.md | 70 ++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/12_1_Verifying_Your_Tor_Setup.md b/12_1_Verifying_Your_Tor_Setup.md index b253e13..ed4de3a 100644 --- a/12_1_Verifying_Your_Tor_Setup.md +++ b/12_1_Verifying_Your_Tor_Setup.md @@ -16,3 +16,73 @@ Configuration was valid ~$ ``` +## Verify bitcoind Tor setup + +You should see something like this in your debug log file to verify your ID onion address. + +``` +$ grep -e "tor: " debug.log +``` +Output + +``` +2020-06-25T18:16:44Z tor: Thread interrupt +2020-06-25T19:11:12Z tor: Got service ID [YOUR_ONION_ID], advertising service your_onion_id.onion:8333 +``` +Using bitcoin-cli you should use: + +``` +$ bitcoin-cli getnetworkinfo +``` +Output + +``` +{ + "version": 200000, + "subversion": "/Satoshi:0.20.0/", + "protocolversion": 70015, + "localservices": "0000000000000409", + "localservicesnames": [ + "NETWORK", + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, + "timeoffset": 0, + "networkactive": true, + "connections": 5, + "networks": [ + { + "name": "ipv4", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "ipv6", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "onion", + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true + } + ], + "relayfee": 0.00001000, + "incrementalfee": 0.00001000, + "localaddresses": [ + { + "address": "your_onion_id.onion", + "port": 8333, + "score": 4 + } + ], + "warnings": "" +} +``` From 710a9f88f7a00c2eb50bba47a2bfbe0778245799 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 30 Jun 2020 23:10:22 +0200 Subject: [PATCH 132/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index eb09b60..ac8086b 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -4,6 +4,6 @@ _This is currently a placeholder; Writing it in Task #15 on the current [TODO li This section will talk about using the Tor services that are now available courtesy of Bitcoin Standup._) - * [12.1: Verifying Your Tor Setup](https://github.com/javiervargas/Learning-Bitcoin-from-the-Command-Line/blob/master/12_1_Verifying_Your_Tor_Setup.md) - * 12.2: Changing Your Bitcoin Hidden Services + * [12.1: Verifying Your Tor Setup](12_1_Verifying_Your_Tor_Setup.md) + * [12.2: Changing Your Bitcoin Hidden Services](12_2_Changing_Your_Bitcoin_Hidden_Services.md) * 12.3: Adding SSH Hiddne Services From 327a1f60159db9c1b9fdc4885dddf6e37d0dde8f Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 11:18:45 -1000 Subject: [PATCH 133/202] contributor update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cd4438..ee7cc51 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ Additional contributions are listed below: | Role | Names | | ------------------- | ---------------------------------------- | -| ***Contributors:*** | [Javier Vargas](https://github.com/javiervargas) (Java secction), [jodobear](https://github.com/jodobear) (Appendix I, Python section) | +| ***Contributors:*** | [gorazdko](https://github.com/gorazdko) (Rust section), [Javier Vargas](https://github.com/javiervargas) (C, Java, Tor sections), [jodobear](https://github.com/jodobear) (Appendix I, Python section) | | ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) | | ***Sponsors:*** | Blockstream Corporation | From d9d73b6574ff167ce9fee39d07069714fb9bd1b8 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 30 Jun 2020 23:26:24 +0200 Subject: [PATCH 134/202] Update 12_1_Verifying_Your_Tor_Setup.md --- 12_1_Verifying_Your_Tor_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_1_Verifying_Your_Tor_Setup.md b/12_1_Verifying_Your_Tor_Setup.md index ed4de3a..64e078e 100644 --- a/12_1_Verifying_Your_Tor_Setup.md +++ b/12_1_Verifying_Your_Tor_Setup.md @@ -18,7 +18,7 @@ Configuration was valid ``` ## Verify bitcoind Tor setup -You should see something like this in your debug log file to verify your ID onion address. +You should see something like this in your debug log file to verify your ID onion address, which confirms you're using an onion hidden service that will bypass firewalls and NAT's and allows you connect to your node remotely using your ID and port. ``` $ grep -e "tor: " debug.log From 3b12f64b1f748dbb923e06b6f80cff6d0d4bac0b Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Tue, 30 Jun 2020 23:42:52 +0200 Subject: [PATCH 135/202] Update 15_3_Receiving_Bitcoind_Notifications_with_C.md --- 15_3_Receiving_Bitcoind_Notifications_with_C.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15_3_Receiving_Bitcoind_Notifications_with_C.md b/15_3_Receiving_Bitcoind_Notifications_with_C.md index 4db5ec8..d638c90 100644 --- a/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ b/15_3_Receiving_Bitcoind_Notifications_with_C.md @@ -76,7 +76,7 @@ Processing triggers for libc-bin (2.27-3ubuntu1) ... ### 2. Create C Program -Now we've installed ZMQ and we can compile our C program using it's notifications. +Now we've installed ZMQ and we can compile our C program using it's notifications. This C program it's a simple client that subscribes to a connection point served by bitcoind and ZMQ interface and reads incoming messages. The program use czmq.h library and receives two parameters as follows, first param is the point exposed by bitcoind and second the topic about we'll listen. ``` c From 0fc9ee4b7dc98fe3f08684b825a5936477c90983 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 11:58:00 -1000 Subject: [PATCH 136/202] 0.20 updates updates to commands and outputs, also a bit of clarity --- 06_4_Sending_a_Transaction_with_a_Locktime.md | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/06_4_Sending_a_Transaction_with_a_Locktime.md b/06_4_Sending_a_Transaction_with_a_Locktime.md index b0ffa64..2a3ebd6 100644 --- a/06_4_Sending_a_Transaction_with_a_Locktime.md +++ b/06_4_Sending_a_Transaction_with_a_Locktime.md @@ -8,13 +8,15 @@ The second way to vary how you send a basic transaction is to choose a locktime. 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. -_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. -_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. -_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 [§9.3: Using CSV in Scripts](09_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 are linked to OP_CHECKLOCKTIMEVERIFY, which is defined in [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) and covered in [§9.2: Using CLTV in Scripts](09_2_Using_CLTV_in_Scripts.md), while relative timelocks are linked to OP_CHECKSEQUENCEVERIFY, which is defined in [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) and also covered in [§9.3](09_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 [§9.3: Using CSV in Scripts](09_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 [§9.2: Using CLTV in Scripts](09_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 [§9.3](09_3_Using_CSV_in_Scripts.md). ## Create a Locktime Transaction @@ -24,17 +26,17 @@ 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. -_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". ### Figure Out Your Locktime By Block Height -Alternatively, you can set the locktime to a smaller number representing a block height. To calculate your future block height, you need to first know what the current block height is. `bitcoin-cli getblockcount` will tell you what your local machine thinks the block height is. You can verify that it's up to date with the `btcblock` alias, which compares the blockheight from your `bitcoind` with a block height taken from the network. +Alternatively, you can set the locktime to a smaller number representing a block height. To calculate your future block height, you need to first know what the current block height is. `bitcoin-cli getblockcount` will tell you what your local machine thinks the block height is. You may want to double-check with a Bitcoin explorer. 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. -_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. @@ -42,23 +44,24 @@ _Why Would I Use a Blockheight?_ Unlike with timestamps, there's no fuzziness fo Once you have figured out your locktime, all you need to do is write up a typical raw transaction, with a third variable for `locktime`: ``` -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.8, "'$changeaddress'": 0.0895 }''' locktime=1119160) +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.001, "'$changeaddress'": 0.00095 }''' locktime=1774650) ``` -Note that this usage of `locktime` is under 500 million, which means that it defines a block height. In this case, it's just a few blocks past the current block height, meant to exemplify how locktime works without sitting around for a long time to wait and see what happens. +Note that this usage of `locktime` is under 500 million, which means that it defines a block height. In this case, it's just a few blocks past the current block height at the time of this writing, meant to exemplify how locktime works without sitting around for a long time to wait and see what happens. Here's what the created transaction looks like: ``` $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex { - "txid": "34650e513b9b84bc47bc10f39ab7f66f59915b65c0c07fdcaf786502d88cec4a", - "hash": "34650e513b9b84bc47bc10f39ab7f66f59915b65c0c07fdcaf786502d88cec4a", - "size": 119, - "vsize": 119, + "txid": "ba440b1dd87a7ccb6a200f087d2265992588284eed0ae455d0672aeb918cf71e", + "hash": "ba440b1dd87a7ccb6a200f087d2265992588284eed0ae455d0672aeb918cf71e", "version": 2, - "locktime": 1119160, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 1774650, "vin": [ { - "txid": "4dcef95a7bb24d907cc0954d75754f8bf1b70cc0542ca071a023abde425a734b", + "txid": "0ad9fb6992dfe4ea90236b69852b3605c0175633b32996a486dcd0b2e739e385", "vout": 1, "scriptSig": { "asm": "", @@ -69,49 +72,49 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex ], "vout": [ { - "value": 0.80000000, + "value": 0.00100000, "n": 0, "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "asm": "0 f333554cc0830d03a9c1f26758e2e7e0f155539f", + "hex": "0014f333554cc0830d03a9c1f26758e2e7e0f155539f", "reqSigs": 1, - "type": "pubkeyhash", + "type": "witness_v0_keyhash", "addresses": [ - "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + "tb1q7ve42nxqsvxs82wp7fn43ch8urc425ul5um4un" ] } - }, + }, { - "value": 0.08950000, + "value": 0.00095000, "n": 1, "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 695c79109dc8424573ca6963bda9beeb5d8a6c68 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914695c79109dc8424573ca6963bda9beeb5d8a6c6888ac", + "asm": "0 a37718a3510958112b6a766e0023ff251b6c2bfb", + "hex": "0014a37718a3510958112b6a766e0023ff251b6c2bfb", "reqSigs": 1, - "type": "pubkeyhash", + "type": "witness_v0_keyhash", "addresses": [ - "mq842Ku2f2ySWpapEwxjuTCjR3Btvz88nx" + "tb1q5dm33g63p9vpz2m2wehqqglly5dkc2lmtmr98d" ] } } ] } ``` -Note that the sequence number (4294967294) is less than 0xffffffff. This is necessary signalling to show that the transaction includes a locktime. It's also done automatically by `bitcoin-cli`. If the sequence number is instead set to 0xffffffff, your locktime will be ignored. +Note that the sequence number (`4294967294`) is less than `0xffffffff`. This is necessary signalling to show that the transaction includes a locktime. It's also done automatically by `bitcoin-cli`. If the sequence number is instead set to `0xffffffff`, your locktime will be ignored. > :information_source: **NOTE — SEQUENCE:** This is the second use of the `nSequence` value in Bitcoin. As with RBF, `nSequence` is again used as an opt-in, this time for the use of locktime. 0xffffffff-1 (4294967294) is the preferred value for signalling locktime because it purposefully disallows the use of both RBF (which requires `nSequence < 0xffffffff-1`) and relative timelock (which requires `nSequence < 0xf0000000`), the other two uses of the `nSequence` value. If you set `nSequence` lower than `0xf0000000`, then you will also relative timelock your transaction, which is probably not what you want. -> :warning: **WARNING:** If you are creating a locktime raw transaction by some other means than `bitcoin-cli`, you will have to set the sequence to less than 0xffffffff by hand. +> :warning: **WARNING:** If you are creating a locktime raw transaction by some other means than `bitcoin-cli`, you will have to set the sequence to less than `0xffffffff` by hand. ## Send Your Transaction By now you're probably well familiar with finishing things up: ``` -$ signedtx=$(bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx error code: -26 error message: -64: non-final +non-final ``` Whoop! What's that error!? @@ -127,7 +130,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. -_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 build 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 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 build 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? From 5bb5b788aa84db92fb9483a690f8725dcea61949 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 12:11:54 -1000 Subject: [PATCH 137/202] updated to 0.20 Just double-checked all inputs and outputs, removed CoinSecrets site that is no longer around. --- 06_5_Sending_a_Transaction_with_Data.md | 66 +++++++++++++------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/06_5_Sending_a_Transaction_with_Data.md b/06_5_Sending_a_Transaction_with_Data.md index 8c0a590..0e4d6b2 100644 --- a/06_5_Sending_a_Transaction_with_Data.md +++ b/06_5_Sending_a_Transaction_with_Data.md @@ -9,10 +9,10 @@ The third way to vary how you send a basic transaction is to use the transaction The first thing you need to do is create the 80 bytes (or less) of data that you'll be recording in your OP_RETURN. This might be as simple as preparing a message or you might be hashing existing data. For example, `sha256sum` produces 256 bits of data, which is 32 bytes, well under the limits: ``` $ sha256sum contract.jpg -fe7f0a3b69f56ef2d055a78823ed3bd1422e46c3183658ea854253033ae0ccef contract.jpg -$ op_return_data="fe7f0a3b69f56ef2d055a78823ed3bd1422e46c3183658ea854253033ae0ccef" +b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75 contract.jpg +$ op_return_data="b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75" ``` -_What is an OP_RETURN?_ All Bitcoin transactions are built upon opcode scripts that we'll meet in the next chapter. The OP_RETURN is a simple opcode that defines a transaction as invalid. Convention has resulted in it being used to embed data on the blockchain. +> :book: _What is an OP_RETURN?_ All Bitcoin transactions are built upon opcode scripts that we'll meet in the next chapter. The OP_RETURN is a simple opcode that defines an OUTPUT as invalid. Convention has resulted in it being used to embed data on the blockchain. ## Prepare Some Money @@ -23,14 +23,16 @@ Here's the standard setup: $ bitcoin-cli listunspent [ { - "txid": "4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927", - "vout": 1, - "address": "my7UvPbPWDbqCxYpAcUZELDbK1X7w9Whmc", - "scriptPubKey": "76a914c101d8c34de7b8d83b3f8d75416ffaea871d664988ac", - "amount": 0.90000000, - "confirmations": 682, + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "vout": 0, + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh", + "scriptPubKey": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "amount": 0.01463400, + "confirmations": 1392, "spendable": true, - "solvable": true + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/12']02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb)#cjr03mru", + "safe": true } ] @@ -43,24 +45,24 @@ $ changeaddress=$(bitcoin-cli getrawchangeaddress) You can now write a new rawtransaction with two outputs: one is your change address to get back (most of) your money, the other is a data address, which is the `bitcoin-cli` term for an OP_RETURN. ``` -$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "data": "'$op_return_data'", "'$changeaddress'": 0.8995 }''') -```#this end in an error: Error parsing JSON:{ "data": "transactie +rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "data": "'$op_return_data'", "'$changeaddress'": 0.0146 }''') +``` Here's what that transaction actually looks like: ``` -$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex { - "txid": "531660f9bcb2571b2b790ebe6e7b6ed40618f608f3f6722a511275257942790b", - "hash": "531660f9bcb2571b2b790ebe6e7b6ed40618f608f3f6722a511275257942790b", - "size": 128, - "vsize": 128, + "txid": "a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8", + "hash": "a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8", "version": 2, + "size": 125, + "vsize": 125, + "weight": 500, "locktime": 0, "vin": [ { - "txid": "4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927", - "vout": 1, + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "vout": 0, "scriptSig": { "asm": "", "hex": "" @@ -73,28 +75,29 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex "value": 0.00000000, "n": 0, "scriptPubKey": { - "asm": "OP_RETURN fe7f0a3b69f56ef2d055a78823ed3bd1422e46c3183658ea854253033ae0ccef", - "hex": "6a20fe7f0a3b69f56ef2d055a78823ed3bd1422e46c3183658ea854253033ae0ccef", + "asm": "OP_RETURN b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75", + "hex": "6a20b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75", "type": "nulldata" } - }, + }, { - "value": 0.89950000, + "value": 0.01460000, "n": 1, "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 166692bda9f25ced145267bb44286e8ee3963d26 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914166692bda9f25ced145267bb44286e8ee3963d2688ac", + "asm": "0 998a9b0ed076bbdec1d88da4f475b9dde75e3620", + "hex": "0014998a9b0ed076bbdec1d88da4f475b9dde75e3620", "reqSigs": 1, - "type": "pubkeyhash", + "type": "witness_v0_keyhash", "addresses": [ - "mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP" + "tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm" ] } } ] } + ``` -As you can see, this sends the majority of the money straight back to the change address (mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP) minus that standard transaction fee we've been using of 0.0005 BTC. More importantly, the first output shows an OP_RETURN with the data (fe7f0a3b69f56ef2d055a78823ed3bd1422e46c3183658ea854253033ae0ccef) right after it. +As you can see, this sends the majority of the money straight back to the change address (`tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm`) minus a small transaction fee. More importantly, the first output shows an OP_RETURN with the data (`b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75`) right after it. ## Send A Raw Transaction @@ -102,17 +105,16 @@ Sign your raw transaction and send it, and soon that OP_RETURN will be embedded ## Check Your OP_RETURN -Again, remember that you can look at this transaction using a blockchain explorer: [https://www.blocktrail.com/tBTC/tx/3a62b396afb8d8a59ebe7b9e52d6aa2485f1082a1d3fc6ece61fb8b55373823d](https://www.blocktrail.com/tBTC/tx/3a62b396afb8d8a59ebe7b9e52d6aa2485f1082a1d3fc6ece61fb8b55373823d) +Again, remember that you can look at this transaction using a blockchain explorer: +[https://live.blockcypher.com/btc-testnet/tx/a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8/](https://live.blockcypher.com/btc-testnet/tx/a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8/) You may note a warning about the data being in an "unknown protocol". If you were designing some regular use of OP_RETURN data, you'd probably mark it with a special prefix, to mark that protocol. Then, the actual OP_RETURN data might be something like "CONTRACTS3b110a164aa18d3a5ab064ba93fdce62". This example didn't use a prefix to avoid muddying the data space. -[Coinsecrets](http://coinsecrets.org/) offers another interesting way to look at OP_RETURN data. It does its best to keep abreast of protocols, so that it can tell you who is doing what in the blockchain. Here's this transaction there: [https://www.blocktrail.com/tBTC/tx/3a62b396afb8d8a59ebe7b9e52d6aa2485f1082a1d3fc6ece61fb8b55373823d](https://www.blocktrail.com/tBTC/tx/3a62b396afb8d8a59ebe7b9e52d6aa2485f1082a1d3fc6ece61fb8b55373823d) - ## Summary: Sending a Transaction with Data 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. -_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 deminstrating 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. From 2c80fcd88c29be0aff5c39bb04c416b6df9ca38c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 12:13:08 -1000 Subject: [PATCH 138/202] Update TODO.md --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 85991e8..a65b8b8 100644 --- a/TODO.md +++ b/TODO.md @@ -18,7 +18,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip ## 2. Upgrade to 0.20 -9. Walk through chapters 1-6, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. +9. Walk through chapters 1-6, making sure all commands work with Bitcoin Core 0.20 (and changing them if not). Redo the output of all examples. **6/19**, **6/23**, **6/30** * Edit Chapter 0 **6/19** * Edit Chapter 1 **6/19** * Re-edit Chapter 2 **6/19** @@ -27,7 +27,7 @@ Replace our current scripts with Bitcoin Standup (which was based on those scrip * Double-check fee calculator in 4.2I with a more complex example **6/19** * Integrate older Curl Interlude **6/19** * Edit & Check Chapter 5 **6/23** - * Edit & Check Chapter 6 **6.1, 6.2, 6.3 done** + * Edit & Check Chapter 6 **6/30** ## 3. Add BTCDEB Support From ae28823666e92b838250dc348cdb691ba50ab21c Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 13:22:25 -1000 Subject: [PATCH 139/202] Update 03_4_Receiving_a_Transaction.md --- 03_4_Receiving_a_Transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_4_Receiving_a_Transaction.md b/03_4_Receiving_a_Transaction.md index bebabb4..c7b3d03 100644 --- a/03_4_Receiving_a_Transaction.md +++ b/03_4_Receiving_a_Transaction.md @@ -311,4 +311,4 @@ Faucets will give you money on the testnet. They come in as raw transactions, wh ## What's Next? -Advance through "bitcoin-cli" with [Chapter Four: Sending Bitcoin Transactions](04_0_Sending_Bitcoin_Transactions.md). +Continue "Understanding Your Bitcoin Setup" with [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md). From 70a7e9094d151efcad4a5bf11ecef471b0c2f7ed Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 13:23:30 -1000 Subject: [PATCH 140/202] Added 3.5 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ee7cc51..acb94ce 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ _This tutorial assumes that you have some minimal background of how to use the c * [3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md) * [Interlude: Using Command-Line Variables](03_3__Interlude_Using_Command-Line_Variables.md) * [3.4: Receiving a Transaction](03_4_Receiving_a_Transaction.md) + * [3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md) + * [4.0: Sending Bitcoin Transactions](04_0_Sending_Bitcoin_Transactions.md) * [4.1: Sending Coins the Easy Way](04_1_Sending_Coins_The_Easy_Way.md) * [4.2: Creating a Raw Transaction](04_2_Creating_a_Raw_Transaction.md) From 9820f499da99cce82cd29e28c0d79d1c6e77fcb5 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 13:25:41 -1000 Subject: [PATCH 141/202] Outlined new section --- 03_5_Understanding_the_Descriptor.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 03_5_Understanding_the_Descriptor.md diff --git a/03_5_Understanding_the_Descriptor.md b/03_5_Understanding_the_Descriptor.md new file mode 100644 index 0000000..8a63937 --- /dev/null +++ b/03_5_Understanding_the_Descriptor.md @@ -0,0 +1,17 @@ +# 3.5: Understanding the Descriptor + +> :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. + +You may have noticed a weird "desc:" field in the `listunspent` command of the previous section. Here's what's all about. + +## Capture a Descriptor + +## Examine a Descriptor + +## Import a Desciptor + +## What's Next? + +Advance through "bitcoin-cli" with [Chapter Four: Sending Bitcoin Transactions](04_0_Sending_Bitcoin_Transactions.md). + +> :fire: What is the power of descriptors? From 04551cb339e0794888ef49484ece8c3d2331aa20 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 13:29:55 -1000 Subject: [PATCH 142/202] Update 03_0_Understanding_Your_Bitcoin_Setup.md --- 03_0_Understanding_Your_Bitcoin_Setup.md | 1 + 1 file changed, 1 insertion(+) diff --git a/03_0_Understanding_Your_Bitcoin_Setup.md b/03_0_Understanding_Your_Bitcoin_Setup.md index 8842858..af8cfb6 100644 --- a/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/03_0_Understanding_Your_Bitcoin_Setup.md @@ -11,6 +11,7 @@ After working through this chapter, a developer will be able to: * Demonstrate that Their Bitcoin Node is Installed and Up-to-date * Create an Address to Receive Bitcoin Funds * Use Basic Wallet Commands + * Import Addresses Supporting objectives include the ability to: From 360b49a8ad1cc62458a6df076e3b060b46ed7a0b Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 13:30:42 -1000 Subject: [PATCH 143/202] Update 03_0_Understanding_Your_Bitcoin_Setup.md --- 03_0_Understanding_Your_Bitcoin_Setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/03_0_Understanding_Your_Bitcoin_Setup.md b/03_0_Understanding_Your_Bitcoin_Setup.md index af8cfb6..7273364 100644 --- a/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/03_0_Understanding_Your_Bitcoin_Setup.md @@ -11,7 +11,7 @@ After working through this chapter, a developer will be able to: * Demonstrate that Their Bitcoin Node is Installed and Up-to-date * Create an Address to Receive Bitcoin Funds * Use Basic Wallet Commands - * Import Addresses + * Create an Address from a Descriptor Supporting objectives include the ability to: @@ -19,6 +19,7 @@ Supporting objectives include the ability to: * Use Basic Informational Commands * Understand What a Bitcoin Address Is * Understand What a Wallet Is + * Understand How to Import Addresses ## Table of Contents From a19f2306a48858478f71df3ce5fa221d79d6309a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 13:31:36 -1000 Subject: [PATCH 144/202] Update 03_0_Understanding_Your_Bitcoin_Setup.md --- 03_0_Understanding_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_0_Understanding_Your_Bitcoin_Setup.md b/03_0_Understanding_Your_Bitcoin_Setup.md index 7273364..86c0788 100644 --- a/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/03_0_Understanding_Your_Bitcoin_Setup.md @@ -28,4 +28,4 @@ Supporting objectives include the ability to: * [Section Three: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md) * [Interlude: Using Command-Line Variables](03_3__Interlude_Using_Command-Line_Variables.md) * [Section Four: Receiving a Transaction](03_4_Receiving_a_Transaction.md) - +* [Section Five: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md) From 678b1909bea34cde3a88c8f9a18ac64d37127fef Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 15:05:44 -1000 Subject: [PATCH 145/202] Update 03_5_Understanding_the_Descriptor.md --- 03_5_Understanding_the_Descriptor.md | 126 ++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/03_5_Understanding_the_Descriptor.md b/03_5_Understanding_the_Descriptor.md index 8a63937..478e446 100644 --- a/03_5_Understanding_the_Descriptor.md +++ b/03_5_Understanding_the_Descriptor.md @@ -4,14 +4,136 @@ You may have noticed a weird "desc:" field in the `listunspent` command of the previous section. Here's what's all about. +## Know about Transferring Addresses + +Most of this course presumes that you're working entirely from a single node where you manage your own wallet, sending and receiving payments with the addresses created by that wallet. However, that's not necessarily how the larger Bitcoin ecosystem works. There, you'd more likely to be moving addresses between wallets and even setting up wallets to watch over funds controlled by different wallets. It's most useful if you're interacting with software _other_ than Bitcoin Core, and really need to lean on this sort of compatibility function, but we'll also use a tiny bit of what we learned here in [§6.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_3_Sending_an_Automated_Multisig.md). + +This functionality used to focus on `xpub` and `xprv`, and those are still supported. + +> :book: ***What is xprv?*** An extended private key. This is the combination of a private key and a chain code. It's a private key that a whole sequence of children private keys can be derived from. + +> :book: ***What is xpub?*** An extended public key. This is the combination of a public key and a chain code. It's a public key that a whole sequence of children public keys can be derived from. + +The fact that you have a "whole sequence of children ... keys" notes that "xpub" and "xprv" aren't standard keys. They're hierarchical keys that can be used to derive whole families of keys, built on the idea of HD Wallets. + +> :book: ***What is an HD Wallet?*** Most modern wallets are actually built on [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This is a hierarchical design where a single seed can be used to generate a whole sequence of keys. The entire wallet may then be restored from that seed, rather than requiring the restoring of every single private key. + +> :book ***What is a Derivation Path?*** When you have hierarchical keys, you need to be able to define individual keys as descendents of a seed. For example `[0]` is the 0th key, `[0/1]` is the first son of the 0th key, `[1/0/1]` is the first grandson of the zeroth son of the 1st key. Some keys also contain a `'` after the number to show they're hardened, which protect them from a specific attack that can be used to derive an `xprv` from an `xpub`. You don't need to worry about the specifics, other than the fact that those `'`s will cause you formatting troubles when working from the command line. + +However, xpubs and xprvs proved insufficient when the types of public keys multiplied under the [SegWit expansion](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), thus the need for "output descriptors". + +> :book: ***What is an output descriptor?*** A precise description of how to derive a Bitcoin address from a combination of a function and one or more inputs to that function. + +The introduction of functions into descriptors is what makes them powerful, because they can be used to transfer all sorts of addresses, from the Legacy addresses that we're working with now to the Segwit and multisig addresses that we'll meet down the road. The function just matches the particular type of address. + ## Capture a Descriptor +Descriptors are visible in several commands such as `listunspent` and `getaddressinfo`: +``` +$ bitcoin-cli getaddressinfo ms7ruzvL4atCu77n47dStMb3of6iScS8kZ +{ + "address": "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ", + "scriptPubKey": "76a9147f437379bcc66c40745edc1891ea6b3830e1975d88ac", + "ismine": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "iswatchonly": false, + "isscript": false, + "iswitness": false, + "pubkey": "03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388", + "iscompressed": true, + "ischange": false, + "timestamp": 1592335136, + "hdkeypath": "m/0'/0'/18'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + "" + ] +} +``` +Here the descriptor is `pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk`. + +## Understand a Descriptor + +A descriptor is broken into several parts: +``` +function([derivation-path]key)#checksum +``` +Here's what that all means: +* **Function.** The function that is used to create an address from that key. In this cases it's `pkh`, which is the standard P2PKH legacy address that you met in [§3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). Similarly, a P2WSH SegWit address would use `wsh` and a P2WPKH address would use `wpkh`. +* **Derivation Path.** This describes what part of an HD wallet is being exported. In this case it's a seed with the fingerprint `d6043800` and then the 18th child of the 0th child of the 0th child (`0'/0'/18'`) of that seed. There may also be a further description after the key: `function([derivation-path]key/more-derivation)#checksum` +* **Key**. The key or keys that are being transferred. This could be something traditional like an `xpub` or `xprv`, it could just be a public key for an address as in this case, it could be a set of addresses for a multi-signature, or it could be something else. This is the core data: the function explains what to do with it. +* **Checksum**. Descriptors are meant to be human transferrable. This checksum makes sure you got it right. + +See [Bitcoin Core's Info on Descriptor Support](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) for more information. + ## Examine a Descriptor +You can look at a descriptor with the `getdescriptorinfo` RPC: +``` +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" +{ + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "checksum": "4ahsl9pk", + "isrange": false, + "issolvable": true, + "hasprivatekeys": false +} +``` +Note that it returns a checksum. If you're ever given a descriptor without a checksum, you can learn it with this command: +``` +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)" +{ + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "checksum": "4ahsl9pk", + "isrange": false, + "issolvable": true, + "hasprivatekeys": false +} +``` +Besides giving you the checksum, this command also provides useful information like whether a descriptor contains private keys. + +The whole point of a descriptor is being able to derive an address in a regular way. This is done with the `deriveaddresses` RPC. +``` +$ bitcoin-cli deriveaddresses "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" +[ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" +] +``` + ## Import a Desciptor +But, the really important thing about a descriptor is that you can take it to another machine and import it. This is done with the `importmulti` RPC using the `desc` option: +``` +remote$ bitcoin-cli importmulti '[{"desc": "pkh([d6043800/0'"'"'/0'"'"'/18'"'"']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", "timestamp": "now", "watchonly": true}]' +[ + { + "success": true + } +] +``` +First, you'll note our first really ugly use of quotes. Every `'` in the derivation path had to be replaced with `'"'"'`. Just expect to have to do that if you're manipulating a descriptor that contains a derivation path. + +Second, you'll note that we flagged this as `watchonly`. That's because we know that it's a public key, so we can't spend with it. If we'd failed to enter this flag, `importmulti` would helpfully have told us something like: `Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.`. + +> :book: ***What is a watch-only address?*** + +Using `getaddressesbylabel`, we can now see that our address has correctly been imported into our remote machine! +``` +remote$ bitcoin-cli getaddressesbylabel "" +{ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ": { + "purpose": "receive" + } +} +``` +## Summary: Understanding the Descriptor + +Descriptors let you pass public keys and private keys among wallets, but more than that, they allow you to precisely and correctly derive addresses of a lot of different sorts from a standardized description format. + +> :fire: ***What is the power of descriptors?*** Descriptors allow you to import and export seeds and keys. As a developer, they also allow you to build up the precise sort of addresses that you're interested in creating. For example, we use it in [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) to generate a multi-sig from three seeds. But generally, when you want to move an address from one device to another, this is how you'll do so. + ## What's Next? Advance through "bitcoin-cli" with [Chapter Four: Sending Bitcoin Transactions](04_0_Sending_Bitcoin_Transactions.md). - -> :fire: What is the power of descriptors? From 95a99ce0cdf5df3c60c80b3f1884aea1eef2c892 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 15:06:50 -1000 Subject: [PATCH 146/202] Update 03_4_Receiving_a_Transaction.md --- 03_4_Receiving_a_Transaction.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/03_4_Receiving_a_Transaction.md b/03_4_Receiving_a_Transaction.md index c7b3d03..8a5f776 100644 --- a/03_4_Receiving_a_Transaction.md +++ b/03_4_Receiving_a_Transaction.md @@ -311,4 +311,7 @@ Faucets will give you money on the testnet. They come in as raw transactions, wh ## What's Next? -Continue "Understanding Your Bitcoin Setup" with [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md). +For a deep dive into how addresses are described, so that they can be transferred or made into parts of a multi-signature, see [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md). + +But if that's too in-depth, continue on to [Chapter Four: Sending Bitcoin Transactions](04_0_Sending_Bitcoin_Transactions.md). + From b8193e9078c12889e51402e5cdd0e0dcbed75a14 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 15:09:35 -1000 Subject: [PATCH 147/202] Update 03_5_Understanding_the_Descriptor.md --- 03_5_Understanding_the_Descriptor.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/03_5_Understanding_the_Descriptor.md b/03_5_Understanding_the_Descriptor.md index 478e446..baa3a02 100644 --- a/03_5_Understanding_the_Descriptor.md +++ b/03_5_Understanding_the_Descriptor.md @@ -2,7 +2,9 @@ > :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. -You may have noticed a weird "desc:" field in the `listunspent` command of the previous section. Here's what's all about. +You may have noticed a weird `desc:` field in the `listunspent` command of the previous section. Here's what's all about (and how it can be used to transfer addresses). + +> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0 that had continued to be expanded through Bitcoin Core 0.20.0. ## Know about Transferring Addresses From 55d10f8d8d1d113441c88ecc8f0739e6975a6ef2 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 15:20:56 -1000 Subject: [PATCH 148/202] Update TODO.md --- TODO.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index a65b8b8..30d739a 100644 --- a/TODO.md +++ b/TODO.md @@ -55,7 +55,9 @@ Add and document the following new concepts: * Write chapter 4.6 **6/23** 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). 13. Add Wallet Updates. - * Bitcoin Descriptors + * Bitcoin Descriptors **6/30** + * Show what a SegWit descriptor looks like + * Show what a multi-sig descriptor looks like * Key Ordering 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). From f27378647d73f93e55777db5384180270ef9acca Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 15:29:30 -1000 Subject: [PATCH 149/202] edit --- 03_5_Understanding_the_Descriptor.md | 29 +++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/03_5_Understanding_the_Descriptor.md b/03_5_Understanding_the_Descriptor.md index baa3a02..c4988d6 100644 --- a/03_5_Understanding_the_Descriptor.md +++ b/03_5_Understanding_the_Descriptor.md @@ -4,29 +4,31 @@ You may have noticed a weird `desc:` field in the `listunspent` command of the previous section. Here's what's all about (and how it can be used to transfer addresses). -> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0 that had continued to be expanded through Bitcoin Core 0.20.0. +> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0 that had continued to be expanded through Bitcoin Core 0.20.0. Most of the commands in this section are from 0.17.0, but the updated `importmulti` that support descriptors is from 0.18.0. ## Know about Transferring Addresses -Most of this course presumes that you're working entirely from a single node where you manage your own wallet, sending and receiving payments with the addresses created by that wallet. However, that's not necessarily how the larger Bitcoin ecosystem works. There, you'd more likely to be moving addresses between wallets and even setting up wallets to watch over funds controlled by different wallets. It's most useful if you're interacting with software _other_ than Bitcoin Core, and really need to lean on this sort of compatibility function, but we'll also use a tiny bit of what we learned here in [§6.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_3_Sending_an_Automated_Multisig.md). +Most of this course presumes that you're working entirely from a single node where you manage your own wallet, sending and receiving payments with the addresses created by that wallet. However, that's not necessarily how the larger Bitcoin ecosystem works. There, you're more likely to be moving addresses between wallets and even setting up wallets to watch over funds controlled by different wallets. -This functionality used to focus on `xpub` and `xprv`, and those are still supported. +That's where descriptors come in. They're most useful if you're interacting with software _other_ than Bitcoin Core, and really need to lean on this sort of compatibility function, but we'll also use a tiny bit of what we learned here in [§6.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_3_Sending_an_Automated_Multisig.md). + +Moving addresses between wallets used to focus on `xpub` and `xprv`, and those are still supported. > :book: ***What is xprv?*** An extended private key. This is the combination of a private key and a chain code. It's a private key that a whole sequence of children private keys can be derived from. > :book: ***What is xpub?*** An extended public key. This is the combination of a public key and a chain code. It's a public key that a whole sequence of children public keys can be derived from. -The fact that you have a "whole sequence of children ... keys" notes that "xpub" and "xprv" aren't standard keys. They're hierarchical keys that can be used to derive whole families of keys, built on the idea of HD Wallets. +The fact that you can have a "whole sequence of children ... keys" reveals the fact that "xpub" and "xprv" aren't standard keys like we've been talking about so far. They're instead hierarchical keys that can be used to create whole families of keys, built on the idea of HD Wallets. -> :book: ***What is an HD Wallet?*** Most modern wallets are actually built on [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This is a hierarchical design where a single seed can be used to generate a whole sequence of keys. The entire wallet may then be restored from that seed, rather than requiring the restoring of every single private key. +> :book: ***What is an HD Wallet?*** Most modern wallets are built on [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This is a hierarchical design where a single seed can be used to generate a whole sequence of keys. The entire wallet may then be restored from that seed, rather than requiring the restoring of every single private key. -> :book ***What is a Derivation Path?*** When you have hierarchical keys, you need to be able to define individual keys as descendents of a seed. For example `[0]` is the 0th key, `[0/1]` is the first son of the 0th key, `[1/0/1]` is the first grandson of the zeroth son of the 1st key. Some keys also contain a `'` after the number to show they're hardened, which protect them from a specific attack that can be used to derive an `xprv` from an `xpub`. You don't need to worry about the specifics, other than the fact that those `'`s will cause you formatting troubles when working from the command line. +> :book ***What is a Derivation Path?*** When you have hierarchical keys, you need to be able to define individual keys as descendents of a seed. For example `[0]` is the 0th key, `[0/1]` is the first son of the 0th key, `[1/0/1]` is the first grandson of the zeroth son of the 1st key. Some keys also contain a `'` after the number, to show they're hardened, which protects them from a specific attack that can be used to derive an `xprv` from an `xpub`. You don't need to worry about the specifics, other than the fact that those `'`s will cause you formatting troubles when working from the command line. -However, xpubs and xprvs proved insufficient when the types of public keys multiplied under the [SegWit expansion](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), thus the need for "output descriptors". +`xpubs` and `xprvs` proved insufficient when the types of public keys multiplied under the [SegWit expansion](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), thus the need for "output descriptors". > :book: ***What is an output descriptor?*** A precise description of how to derive a Bitcoin address from a combination of a function and one or more inputs to that function. -The introduction of functions into descriptors is what makes them powerful, because they can be used to transfer all sorts of addresses, from the Legacy addresses that we're working with now to the Segwit and multisig addresses that we'll meet down the road. The function just matches the particular type of address. +The introduction of functions into descriptors is what makes them powerful, because they can be used to transfer all sorts of addresses, from the Legacy addresses that we're working with now to the Segwit and multisig addresses that we'll meet down the road. An individual function matches a particular type of address and correlates with specific rules to generate that address. ## Capture a Descriptor @@ -64,7 +66,7 @@ function([derivation-path]key)#checksum ``` Here's what that all means: * **Function.** The function that is used to create an address from that key. In this cases it's `pkh`, which is the standard P2PKH legacy address that you met in [§3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). Similarly, a P2WSH SegWit address would use `wsh` and a P2WPKH address would use `wpkh`. -* **Derivation Path.** This describes what part of an HD wallet is being exported. In this case it's a seed with the fingerprint `d6043800` and then the 18th child of the 0th child of the 0th child (`0'/0'/18'`) of that seed. There may also be a further description after the key: `function([derivation-path]key/more-derivation)#checksum` +* **Derivation Path.** This describes what part of an HD wallet is being exported. In this case it's a seed with the fingerprint `d6043800` and then the 18th child of the 0th child of the 0th child (`0'/0'/18'`) of that seed. There may also be a further derivation after the key: `function([derivation-path]key/more-derivation)#checksum` * **Key**. The key or keys that are being transferred. This could be something traditional like an `xpub` or `xprv`, it could just be a public key for an address as in this case, it could be a set of addresses for a multi-signature, or it could be something else. This is the core data: the function explains what to do with it. * **Checksum**. Descriptors are meant to be human transferrable. This checksum makes sure you got it right. @@ -96,13 +98,14 @@ $ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b2 ``` Besides giving you the checksum, this command also provides useful information like whether a descriptor contains private keys. -The whole point of a descriptor is being able to derive an address in a regular way. This is done with the `deriveaddresses` RPC. +One of the powers of a descriptor is being able to derive an address in a regular way. This is done with the `deriveaddresses` RPC. ``` $ bitcoin-cli deriveaddresses "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" [ "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" ] ``` +You'll note it loops back to the address we started with (as it should). ## Import a Desciptor @@ -119,7 +122,7 @@ First, you'll note our first really ugly use of quotes. Every `'` in the derivat Second, you'll note that we flagged this as `watchonly`. That's because we know that it's a public key, so we can't spend with it. If we'd failed to enter this flag, `importmulti` would helpfully have told us something like: `Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.`. -> :book: ***What is a watch-only address?*** +> :book: ***What is a watch-only address?*** A watch-only address allows you to watch for transactions related to an address (or to a whole family of addresses if you used an `xpub`), but not to spend funds on those addresses. Using `getaddressesbylabel`, we can now see that our address has correctly been imported into our remote machine! ``` @@ -132,9 +135,9 @@ remote$ bitcoin-cli getaddressesbylabel "" ``` ## Summary: Understanding the Descriptor -Descriptors let you pass public keys and private keys among wallets, but more than that, they allow you to precisely and correctly derive addresses of a lot of different sorts from a standardized description format. +Descriptors let you pass public keys and private keys among wallets, but more than that, they allow you to precisely and correctly to define addresses and to derive addresses of a lot of different sorts from a standardized description format. -> :fire: ***What is the power of descriptors?*** Descriptors allow you to import and export seeds and keys. As a developer, they also allow you to build up the precise sort of addresses that you're interested in creating. For example, we use it in [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) to generate a multi-sig from three seeds. But generally, when you want to move an address from one device to another, this is how you'll do so. +> :fire: ***What is the power of descriptors?*** Descriptors allow you to import and export seeds and keys. That's great if you want to move between different wallets. As a developer, they also allow you to build up the precise sort of addresses that you're interested in creating. For example, we use it in [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) to generate a multi-sig from three seeds. ## What's Next? From ccf038274d99e76ccd38e6d10f3a833cb177d091 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 30 Jun 2020 15:33:36 -1000 Subject: [PATCH 150/202] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index acb94ce..090a6cc 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART TWO: USING BITCOIN-CLI -**Status:** Requires editing; requires check that it works in 0.20; requires concepts brought up to 0.20. +**Status:** Needs new content on (1) PSBTs; (2) sorted multisigs; and (3) if appropriate HWI. Also needs a little integration of descriptors in later chapters (3.5, 6.2+) * [3.0: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md) * [3.1: Verifying Your Bitcoin Setup](03_1_Verifying_Your_Bitcoin_Setup.md) From c8b92bc287ac128ea7bab911f7689c7c7615f2b6 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 14:57:09 +1000 Subject: [PATCH 151/202] revision --- 18_1_Accessing_Bitcoind_with_Go.md | 87 +++++++++++++++++++++++--- 18_3_Accessing_Bitcoind_with_NodeJS.md | 2 +- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index d4341ae..4dce43c 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -50,7 +50,7 @@ $ mkdir $HOME/work ## Setup btcd rpcclient -We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. We can use ```go get``` to download it: +We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. Although btcd was originally designed to work with the btcd Bitcoin full node, it also works with Bitcoin core. It has some quirks which we will be looking at. We can use ```go get``` to download it: ``` $ go get github.com/btcsuite/btcd/rpcclient @@ -69,6 +69,7 @@ Modify the ```main.go``` file and enter the details associated with your Bitcoin User: "bitcoinrpc", Pass: "d8340efbcd34e312044c8431c59c792c", ``` +> **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup. Now run: @@ -130,7 +131,15 @@ func main() { } ``` -Make sure to change your username and password to those from your ```~/.bitcoin/bitcoin.conf``` file. When you run this: +Make sure to change your username and password to those from your ```~/.bitcoin/bitcoin.conf``` file. + +The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. For example, ```bitcoin-cli getblockcount``` is ```client.GetBlockCount``` in Go. The ```connCfg``` parameters allow you to choose the Bitcoin RPC port, username, password and whether you are on testnet or mainnet. Using ```rpcclient.New(connCfg, nil)``` we configure ```client``` to connect to our Bitcoin node. + +The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt" and "github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. + +A quirk with hashes in rpcclient is that they will typically print in a different encoding if you were to print it normally with ```blockHash```. In order to print them as a string, we need to use ```blockHash.String()```. + +We can run Go code with ```go run main.go```: ``` $ go run main.go @@ -142,7 +151,7 @@ The latest block number along with its hash should be printed out. ### Getting your wallet balance -Since the btcd rpcclient is quite limited, we can't make a use the ```getwalletinfo``` functino, however we can get the balance of our wallet: +Since the btcd rpcclient has some limits, we can't make a use of the ```getwalletinfo``` function, however we can get the balance of our wallet: ``` package main @@ -171,6 +180,7 @@ func main() { if err != nil { log.Fatal(err) } + fmt.Println(wallet) } ``` @@ -181,6 +191,50 @@ You should get an output similar to this: 0.000689 BTC ``` +```client.GetBalance("*")``` requires the ```"*"``` input, due to a quirk with btcd. The asterisk signifies that we want to get the balance of all our wallets. + +### Generate an address + +We can generate addresses, but we can't specify the address type: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + Params: chaincfg.TestNet3Params.Name, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + address, err := client.GetNewAddress("") + if err != nil { + log.Fatal(err) + } + fmt.Println(address) +} +``` +> **MAINNET VS TESTNET:** ```Params: chaincfg.TestNet3Params.Name,``` should be ```Params: chaincfg.MainNetParams.Name,``` on mainnet. + +You may notice that the ```connCfg``` clause is different in this example. ```Params: chaincfg.TestNet3Params.Name,``` is added here, so that the rpcclient knows that we are dealing with testnet addresses. You would change ```chaincfg.TestNet3Params.Name``` to ```chaincfg.MainNetParams.Name``` if you were on mainnet. This specification is only required during address generation, which is why I only kept it in this example. You can include this in other examples as well, but it isn't necessary. Make sure to import ```"github.com/btcsuite/btcd/chaincfg"``` if you are using it. + +A quirk with ```client.GetNewAddress("")``` is that an empty string needs to be included for it to work. + ### Get amount received by an address We can retrieve the amount of Bitcoin received by a specific address: @@ -216,12 +270,22 @@ func main() { log.Fatal(err) } wallet, err := client.GetReceivedByAddress(addr) + if err != nil { + log.Fatal(err) + } fmt.Println(wallet) } ``` +> **MAINNET VS TESTNET:** ```&chaincfg.TestNet3Params``` should be ```&chaincfg.TestNet3Params``` on mainnet. -The defaultNet variable is used to specify whether our Bitcoin node is on testnet or on mainnet. +You should get an output similar to this: + +``` +0.000089 BTC +``` + +The defaultNet variable is used to specify whether our Bitcoin node is on testnet or on mainnet. This example requires us to import the ```"github.com/btcsuite/btcutil"``` and ```"github.com/btcsuite/btcd/chaincfg"``` libraries. ```btcutil``` allows for a Bitcoin address to be decoded in a way that the rpcclient can understand. This is necessary when working with addresses in rpcclient. ```chaincfg``` is used to configure our chain as the Testnet chain. This is necessary for address decoding since the addresses used on Mainnet and Testnet are different. ### Sending Bitcoin to an address @@ -255,16 +319,20 @@ func main() { if err != nil { log.Fatal(err) } - sent, err := client.SendToAddress(addr, btcutil.Amount(1e4)) if err != nil { log.Fatal(err) } + fmt.Println(sent) } ``` -This outputs the txid of the transaction. +After the transaction is sent, the txid of the transaction is outputted: + +``` +9aa4cd6559e0d69059eae142c35bfe78b71a8084e1fcc2c74e2a9675e9e7489d +``` ### Lookup a transaction @@ -300,6 +368,7 @@ func main() { if err != nil { log.Fatal(err) } + fmt.Println(transactions) } ``` @@ -332,6 +401,8 @@ This prints out the details associated with a transaction, such as its amount an } ``` -## Summary: Accessing Bitcoind with Node +```"github.com/btcsuite/btcd/chaincfg/chainhash"``` is imported in order to allow hashes to be stored in the Go code. ```chainhash.NewHashFromStr("hash")``` converts a hash in a string, to a format that works with rpcclient. -Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. +## Summary: Accessing Bitcoind with Go + +Although the btcd rpcclient has some limits, we can still perform the main rpc commands in Go. The documentation for rpcclient is available on [Godoc](https://godoc.org/github.com/btcsuite/btcd/rpcclient). If the documentation doesn't have what your looking for, have a look at the [btcd repository](https://github.com/btcsuite/btcd). It is generally well documented and easy to read. Based on these examples you should be able to incorporate Bitcoin in a Go project and do things like sending and receiving coins. \ No newline at end of file diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index a133071..71138a2 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -251,4 +251,4 @@ We can also use the ```getTransaction``` function to view how many confirmations ## Summary: Accessing Bitcoind with Node -With BCRPC we can do all the commands available through ```bitcoin-cli```, in JavaScript. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins. +With BCRPC we can do all the commands available through ```bitcoin-cli```, in JavaScript. The [BCRPC README](https://github.com/dgarage/bcrpc) has some examples which use promises (the examples in this document use callbacks). The [JavaScript behind it](https://github.com/dgarage/bcrpc/blob/master/index.js) is short and readable. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins. From f6b5fac2f8dcdc49ca2ba767da18f0ee64ec482d Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:05:35 +1000 Subject: [PATCH 152/202] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 2 +- 18_3_Accessing_Bitcoind_with_NodeJS.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 4dce43c..8d6d2ee 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -50,7 +50,7 @@ $ mkdir $HOME/work ## Setup btcd rpcclient -We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. Although btcd was originally designed to work with the btcd Bitcoin full node, it also works with Bitcoin core. It has some quirks which we will be looking at. We can use ```go get``` to download it: +We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. Although rpcclient was originally designed to work with the btcd Bitcoin full node, it also works with Bitcoin core. It has some quirks which we will be looking at. We can use ```go get``` to download it: ``` $ go get github.com/btcsuite/btcd/rpcclient diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 71138a2..7f4bd11 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -31,6 +31,7 @@ $ export BITCOIND_PORT=18332 ``` > **WARNING:** Obviously, you'd never put set your password in an environmental variable in a production environment. + > **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup. You can now verify everything is working correctly: @@ -98,6 +99,17 @@ You can run it with ```$ node server.js```. You should get an output similar to 0000000000000083d29c524d4cfc257adfab8fa9b6f0d207d1d0f1b63e1de11e ``` +The BCRPC functions can accept inputs. For example, ```getBlockHash``` takes ```blockCount.result``` as an input. The result of the BCRPC functions is a JSON object containing information about any errors and the id of the request. When accessing our result, we add ```.result``` to the end of it to specify that we are interested in the actual result, not information about errors. This is what output of the above example would look like if we replaced ```console.log(blockCount.result);``` and ```console.log(hash.result);``` with ```console.log(blockCount);``` and ```console.log(hash);```, respectively: + +``` +{ result: 1774686, error: null, id: null } +{ + result: '00000000000000d980c495a2b7addf09bb0a9c78b5b199c8e965ee54753fa5da', + error: null, + id: null +} +``` + ## Look Up Your Wallet You can also lookup your wallet and view your balance, transaction count et cetera: From 241d4d78c840cc19ea5b3eb2e097be9f1b2fa351 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:09:08 +1000 Subject: [PATCH 153/202] updated --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 7f4bd11..196bf5e 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -164,6 +164,15 @@ Output: mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ ``` +This example shows how we can use the same flags as ```bitcoin-cli``` in BCRPC. The example above would look like this from the command line: + +``` +$ bitcoin-cli getnewaddress -addresstype legacy +mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ +``` + +In BCRPC ```getnewaddress``` is in camelCase (```getNewAddress```) and the flags are normally separated by spaces are put in strings and separated by commas. + ### List transactions We can list our previous transactions and view information about transactions such as amount and number of confirmations: From df25525768f52ae2ced958b2f2c8fa0f4ff4bc45 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:09:43 +1000 Subject: [PATCH 154/202] updated --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 196bf5e..0b2ef0e 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -171,7 +171,7 @@ $ bitcoin-cli getnewaddress -addresstype legacy mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ ``` -In BCRPC ```getnewaddress``` is in camelCase (```getNewAddress```) and the flags are normally separated by spaces are put in strings and separated by commas. +In BCRPC ```getnewaddress``` is in camelCase (```getNewAddress```) and the that flags are normally separated by spaces are instead put in strings and separated by commas. ### List transactions From 325299f087f4f48530ecdfb8c210a65ec4b0e664 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:27:48 +1000 Subject: [PATCH 155/202] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 8d6d2ee..0994bd9 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -135,7 +135,9 @@ Make sure to change your username and password to those from your ```~/.bitcoin/ The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. For example, ```bitcoin-cli getblockcount``` is ```client.GetBlockCount``` in Go. The ```connCfg``` parameters allow you to choose the Bitcoin RPC port, username, password and whether you are on testnet or mainnet. Using ```rpcclient.New(connCfg, nil)``` we configure ```client``` to connect to our Bitcoin node. -The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt" and "github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. +The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt"``` and ```"github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. + +The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. A quirk with hashes in rpcclient is that they will typically print in a different encoding if you were to print it normally with ```blockHash```. In order to print them as a string, we need to use ```blockHash.String()```. From efee6e2224ac1b99a87a07b58d44c08a84385d9b Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:33:54 +1000 Subject: [PATCH 156/202] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 0994bd9..b6b995c 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -137,11 +137,18 @@ The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt"``` and ```"github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. -The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. +The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. After the ```defer client.Shutdown()``` line is where the exciting stuff is, like ```client.GetBlockCount()``` and ```client.GetBlockHash(blockCount)```. + +The rpcclient functions can take inputs as well, for example ```client.GetBlockHash(blockCount)``` takes the block count as an input. The ```client.GetBlockHash(blockCount)``` from above would look like this as a ```bitcoin-cli``` command: + +``` +$ bitcoin-cli getblockhash 1773561 +00000000000000346bab4126f418a5820692c9a7de7ef79717bebfccebacad61 +``` A quirk with hashes in rpcclient is that they will typically print in a different encoding if you were to print it normally with ```blockHash```. In order to print them as a string, we need to use ```blockHash.String()```. -We can run Go code with ```go run main.go```: +We can run the Go code with ```go run main.go``` and we should get an output that looks like this: ``` $ go run main.go From 1efdd57bc5f657d47892aca75d7d083671406631 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:34:54 +1000 Subject: [PATCH 157/202] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index b6b995c..253748a 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -137,7 +137,7 @@ The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt"``` and ```"github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. -The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. After the ```defer client.Shutdown()``` line is where the exciting stuff is, like ```client.GetBlockCount()``` and ```client.GetBlockHash(blockCount)```. +The ```defer client.Shutdown()``` line is for disconnecting from our Bitcoin node, once the ```main()``` function finishes executing. After the ```defer client.Shutdown()``` line is where the exciting stuff is, like ```client.GetBlockCount()``` and ```client.GetBlockHash(blockCount)```. The rpcclient functions can take inputs as well, for example ```client.GetBlockHash(blockCount)``` takes the block count as an input. The ```client.GetBlockHash(blockCount)``` from above would look like this as a ```bitcoin-cli``` command: From b3145deca7925f4336a5b953e41b6b6784f8ca26 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 13:59:26 +0200 Subject: [PATCH 158/202] Update 15_3_Receiving_Bitcoind_Notifications_with_C.md --- ...Receiving_Bitcoind_Notifications_with_C.md | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/15_3_Receiving_Bitcoind_Notifications_with_C.md b/15_3_Receiving_Bitcoind_Notifications_with_C.md index d638c90..7b06a41 100644 --- a/15_3_Receiving_Bitcoind_Notifications_with_C.md +++ b/15_3_Receiving_Bitcoind_Notifications_with_C.md @@ -76,8 +76,14 @@ Processing triggers for libc-bin (2.27-3ubuntu1) ... ### 2. Create C Program -Now we've installed ZMQ and we can compile our C program using it's notifications. This C program it's a simple client that subscribes to a connection point served by bitcoind and ZMQ interface and reads incoming messages. -The program use czmq.h library and receives two parameters as follows, first param is the point exposed by bitcoind and second the topic about we'll listen. +Now we've installed ZMQ and we can compile our C program using it's notifications. This C program it's a simple client that subscribes to a connection point served by bitcoind and ZMQ interface and reads incoming messages. +The program use czmq.h library and receives two parameters as follows, first param is the point exposed by bitcoind that should be tcp connection point depending second param that could be one of these: + +zmqpubrawblock +zmqpubrawtx +zmqpubhashtx +zmqpubhashblock + ``` c #include @@ -134,6 +140,24 @@ gcc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq ### 4. Configure ZMQ on bitcoind +#### ZMQ + +ZeroMQ 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. As the purpose of this chapter is to show how to receive bitcoind notifications in the C language, ZMQ will be used for it. + +Currently, the ZeroMQ facility only needs to have the ZeroMQ endpoint specified. ZeroMQ publish sockets prepend each data item with an arbitrary topic +prefix that allows subscriber clients to request only those items with a matching prefix. + +Topics. + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +zmqpubhashtx=tcp://127.0.0.1:28334 +zmqpubhashblock=tcp://127.0.0.1:28335 +``` + +In this example we'll use raw tx that is the topic that notifies about new transactions in raw format. + Add this lines to bitcoin.conf file and restart daemon. ``` @@ -162,6 +186,8 @@ Output: ``` ### 5. Execute listener: +When you execute chainlistener and passes these params you'll get an output like this: + ``` $ ./chainlistener tcp://127.0.0.1:28333 rawtx Size: 250 @@ -178,7 +204,9 @@ Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA1 No: 70 ....... ``` +The first param it's bitcoind connection point where ZMQ will notifies all about transactions in raw format. It corresponds to this line in bitcoin.conf file zmqpubrawtx=tcp://127.0.0.1:28333 +The second param is the topic selected rawtx explained above. ### For More Information From 0ee6893d477259b979b3a5ca8c51ee0f7d34fd20 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 15:46:14 +0200 Subject: [PATCH 159/202] Update 12_1_Verifying_Your_Tor_Setup.md --- 12_1_Verifying_Your_Tor_Setup.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/12_1_Verifying_Your_Tor_Setup.md b/12_1_Verifying_Your_Tor_Setup.md index 64e078e..1795da0 100644 --- a/12_1_Verifying_Your_Tor_Setup.md +++ b/12_1_Verifying_Your_Tor_Setup.md @@ -29,7 +29,17 @@ Output 2020-06-25T18:16:44Z tor: Thread interrupt 2020-06-25T19:11:12Z tor: Got service ID [YOUR_ONION_ID], advertising service your_onion_id.onion:8333 ``` -Using bitcoin-cli you should use: +Using bitcoin-cli you should use getnetworkinfo to get your onion id like this: + +``` + "localaddresses": [ + { + "address": "your_onion_id.onion", + "port": 8333, + "score": 4 + } + ], +``` ``` $ bitcoin-cli getnetworkinfo From 661eaf6a3e5252c2aaa9ab078b7e5f62984c90ad Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:08:38 +0200 Subject: [PATCH 160/202] Update 12_2_Changing_Your_Bitcoin_Hidden_Services.md --- 12_2_Changing_Your_Bitcoin_Hidden_Services.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/12_2_Changing_Your_Bitcoin_Hidden_Services.md b/12_2_Changing_Your_Bitcoin_Hidden_Services.md index a882878..59c835b 100644 --- a/12_2_Changing_Your_Bitcoin_Hidden_Services.md +++ b/12_2_Changing_Your_Bitcoin_Hidden_Services.md @@ -13,6 +13,12 @@ Add your user to debian-tor group like this: ~$ sudo usermod -a -G debian-tor [CHANGE_MY_USER] ``` +If you're running a older version Tor like 0.2.7 add this lines to /etc/tor/torrc file: + +``` +HiddenServiceDir /var/lib/tor/bitcoin-service/ +HiddenServicePort 8333 127.0.0.1:8333 +HiddenServicePort 18333 127.0.0.1:18333 +``` +If you're running Tor version 3 bitcoind will configurate hidden services to listen on. - ll /run/tor/control.authcookie --rw-r----- 1 debian-tor debian-tor 32 jun 26 09:44 /run/tor/control.authcookie From e038f6376ec356fbdabdf1f8d43b149defd1d236 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:09:43 +0200 Subject: [PATCH 161/202] Update 12_2_Changing_Your_Bitcoin_Hidden_Services.md --- 12_2_Changing_Your_Bitcoin_Hidden_Services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_2_Changing_Your_Bitcoin_Hidden_Services.md b/12_2_Changing_Your_Bitcoin_Hidden_Services.md index 59c835b..33ea475 100644 --- a/12_2_Changing_Your_Bitcoin_Hidden_Services.md +++ b/12_2_Changing_Your_Bitcoin_Hidden_Services.md @@ -20,5 +20,5 @@ HiddenServiceDir /var/lib/tor/bitcoin-service/ HiddenServicePort 8333 127.0.0.1:8333 HiddenServicePort 18333 127.0.0.1:18333 ``` -If you're running Tor version 3 bitcoind will configurate hidden services to listen on. +If you're running Tor version 3 bitcoind will configurate hidden services automatically to listen on. From e7f0bc278e0e1121e1fa9cc44a8ed20e0e727a29 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:13:20 +0200 Subject: [PATCH 162/202] Update 12_2_Changing_Your_Bitcoin_Hidden_Services.md --- 12_2_Changing_Your_Bitcoin_Hidden_Services.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/12_2_Changing_Your_Bitcoin_Hidden_Services.md b/12_2_Changing_Your_Bitcoin_Hidden_Services.md index 33ea475..7b73d7e 100644 --- a/12_2_Changing_Your_Bitcoin_Hidden_Services.md +++ b/12_2_Changing_Your_Bitcoin_Hidden_Services.md @@ -7,7 +7,13 @@ In this chapter we will show you how to create or change your local Bitcoin Hidd -rw-r----- 1 debian-tor debian-tor 32 jun 26 09:44 /run/tor/control.authcookie ``` -Add your user to debian-tor group like this: +To avoid see a message like this in debug log file you need to add your current user to debian-tor group like this: + +debug.log + +``` +2020-05-15T16:49:20Z tor: Authentication cookie /run/tor/control.authcookie could not be opened (check permissions) +``` ``` ~$ sudo usermod -a -G debian-tor [CHANGE_MY_USER] From e629b48481dca1c4140287074aa105af37aa09d0 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:45:08 +0200 Subject: [PATCH 163/202] Create 12_3_Adding_SSH_Hidden_Services --- 12_3_Adding_SSH_Hidden_Services | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 12_3_Adding_SSH_Hidden_Services diff --git a/12_3_Adding_SSH_Hidden_Services b/12_3_Adding_SSH_Hidden_Services new file mode 100644 index 0000000..5e1a562 --- /dev/null +++ b/12_3_Adding_SSH_Hidden_Services @@ -0,0 +1,50 @@ +# Chapter 12.3: Adding SSH Hidden Services + +In this chapter we will show you how to add a ssh hidden service to login remotelly using tor. + +## Create SSH Hidden Services + +To create new service you need to add some lines in your torrcfile. + +This should be under /etc/tor/torrc + +Add this lines: + +``` +HiddenServiceDir /var/lib/tor/hidden-service-ssh/ +HiddenServicePort 22 127.0.0.1:22 +HiddenServiceAuthorizeClient stealth hidden-service-ssh +``` + +* HiddenServiceDir indicates tor that you have a hidden service directory with the neccesary configuration on path. +* HiddenServicePort indicates tor port to be used, in SSH case is 22, if you want use other port you can change here. +* HiddenServiceAuthorizeClient As it's name indicates authorize a client to connect to the hidden service. + +After add lines to tor file you need to restart tor service + +``` +sudo /etc/init.d/tor restart +``` + +After restart you should have three new files like this: + +``` +total 24 +drwx--S--- 3 debian-tor debian-tor 4096 jul 1 18:39 ./ +drwx--S--- 5 debian-tor debian-tor 4096 jul 1 18:39 ../ +drwx--S--- 2 debian-tor debian-tor 4096 jul 1 18:39 authorized_clients/ +-rw------- 1 debian-tor debian-tor 63 jul 1 18:39 hostname +-rw------- 1 debian-tor debian-tor 64 jul 1 18:39 hs_ed25519_public_key +-rw------- 1 debian-tor debian-tor 96 jul 1 18:39 hs_ed25519_secret_key +``` +The file hostname contains your id onion. + +Use this address to connect to your ssh hidden service like this: + +``` +torify ssh @your_new_onion_id.onion +``` + + + + From bedcf765a53244873876267993a51be186473d11 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:46:28 +0200 Subject: [PATCH 164/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index ac8086b..ad8fa68 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -6,4 +6,4 @@ This section will talk about using the Tor services that are now available court * [12.1: Verifying Your Tor Setup](12_1_Verifying_Your_Tor_Setup.md) * [12.2: Changing Your Bitcoin Hidden Services](12_2_Changing_Your_Bitcoin_Hidden_Services.md) - * 12.3: Adding SSH Hiddne Services + * [12.3: Adding SSH Hiddne Services](12_3_Adding_SSH_Hidden_Services) From 9439de608b7e9583a8d1354f102b182575f76ae9 Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:46:41 +0200 Subject: [PATCH 165/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index ad8fa68..d8f97ec 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -6,4 +6,4 @@ This section will talk about using the Tor services that are now available court * [12.1: Verifying Your Tor Setup](12_1_Verifying_Your_Tor_Setup.md) * [12.2: Changing Your Bitcoin Hidden Services](12_2_Changing_Your_Bitcoin_Hidden_Services.md) - * [12.3: Adding SSH Hiddne Services](12_3_Adding_SSH_Hidden_Services) + * [12.3: Adding SSH Hidden Services](12_3_Adding_SSH_Hidden_Services) From 3e4ec41fab0838a5f9e1c176683f1348a1104cae Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:47:30 +0200 Subject: [PATCH 166/202] Update 12_3_Adding_SSH_Hidden_Services --- 12_3_Adding_SSH_Hidden_Services | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/12_3_Adding_SSH_Hidden_Services b/12_3_Adding_SSH_Hidden_Services index 5e1a562..76b1d12 100644 --- a/12_3_Adding_SSH_Hidden_Services +++ b/12_3_Adding_SSH_Hidden_Services @@ -16,9 +16,9 @@ HiddenServicePort 22 127.0.0.1:22 HiddenServiceAuthorizeClient stealth hidden-service-ssh ``` -* HiddenServiceDir indicates tor that you have a hidden service directory with the neccesary configuration on path. -* HiddenServicePort indicates tor port to be used, in SSH case is 22, if you want use other port you can change here. -* HiddenServiceAuthorizeClient As it's name indicates authorize a client to connect to the hidden service. +* HiddenServiceDir: indicates tor that you have a hidden service directory with the neccesary configuration on path. +* HiddenServicePort: indicates tor port to be used, in SSH case is 22, if you want use other port you can change here. +* HiddenServiceAuthorizeClient: As it's name indicates authorize a client to connect to the hidden service. After add lines to tor file you need to restart tor service From 8d93aa2efcab8e153fba6c10e528d35b5e60267f Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 1 Jul 2020 18:50:08 +0200 Subject: [PATCH 167/202] Update and rename 12_3_Adding_SSH_Hidden_Services to 12_3_Adding_SSH_Hidden_Services.md --- ...SH_Hidden_Services => 12_3_Adding_SSH_Hidden_Services.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename 12_3_Adding_SSH_Hidden_Services => 12_3_Adding_SSH_Hidden_Services.md (89%) diff --git a/12_3_Adding_SSH_Hidden_Services b/12_3_Adding_SSH_Hidden_Services.md similarity index 89% rename from 12_3_Adding_SSH_Hidden_Services rename to 12_3_Adding_SSH_Hidden_Services.md index 76b1d12..d04735a 100644 --- a/12_3_Adding_SSH_Hidden_Services +++ b/12_3_Adding_SSH_Hidden_Services.md @@ -1,10 +1,10 @@ # Chapter 12.3: Adding SSH Hidden Services -In this chapter we will show you how to add a ssh hidden service to login remotelly using tor. +In this chapter we will show you how to add a ssh hidden service to login remotelly using Tor. ## Create SSH Hidden Services -To create new service you need to add some lines in your torrcfile. +To create new service you need to add some lines in your torrc file. This should be under /etc/tor/torrc @@ -16,7 +16,7 @@ HiddenServicePort 22 127.0.0.1:22 HiddenServiceAuthorizeClient stealth hidden-service-ssh ``` -* HiddenServiceDir: indicates tor that you have a hidden service directory with the neccesary configuration on path. +* HiddenServiceDir: indicates tor that you have a hidden service directory with the necessary configuration on path. * HiddenServicePort: indicates tor port to be used, in SSH case is 22, if you want use other port you can change here. * HiddenServiceAuthorizeClient: As it's name indicates authorize a client to connect to the hidden service. From f35b55cf98e096a94c53957794f4feb1488b6c4d Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Thu, 2 Jul 2020 12:43:08 +0200 Subject: [PATCH 168/202] Update 12_0_Using_Tor.md --- 12_0_Using_Tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12_0_Using_Tor.md b/12_0_Using_Tor.md index d8f97ec..853ef5f 100644 --- a/12_0_Using_Tor.md +++ b/12_0_Using_Tor.md @@ -6,4 +6,4 @@ This section will talk about using the Tor services that are now available court * [12.1: Verifying Your Tor Setup](12_1_Verifying_Your_Tor_Setup.md) * [12.2: Changing Your Bitcoin Hidden Services](12_2_Changing_Your_Bitcoin_Hidden_Services.md) - * [12.3: Adding SSH Hidden Services](12_3_Adding_SSH_Hidden_Services) + * [12.3: Adding SSH Hidden Services](12_3_Adding_SSH_Hidden_Services.md) From ef3d613d4ccab5578ea20f14f111124eba2b2a52 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 10:55:34 -1000 Subject: [PATCH 169/202] added descriptor information --- 04_6_Creating_a_Segwit_Transaction.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/04_6_Creating_a_Segwit_Transaction.md b/04_6_Creating_a_Segwit_Transaction.md index 2aad529..94b705a 100644 --- a/04_6_Creating_a_Segwit_Transaction.md +++ b/04_6_Creating_a_Segwit_Transaction.md @@ -269,6 +269,12 @@ e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c ``` It all works exactly the same as other sorts of transactions! +### Recognize the New Descriptor + +If you look at the `desc` field, you'll note that the SegWit address has a different style descriptor than those encountered in [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md). A legacy descriptor described in that section looked like this: `pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk`. Our new SegWit descriptor instead looks like this: `wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp"`. + +The big thing to note is that function has changed. It was previously `pkh`, which is a standard P2PKH hashed public-key address. The SegWit address is instead `wpkh`, which means that it's a P2WPKH native SegWit address. This underlines the :fire: ***power of descriptors***. They describe how to create an address from a key or other information, with the functions unambiguously defining how to make the address based on its type. + ## Summary: Creating a SegWit Transaction 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. From a2f5dd388aab2e7dcccc9425dcc6f016162e4fa7 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 10:56:33 -1000 Subject: [PATCH 170/202] Update TODO.md --- TODO.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 30d739a..7eae7da 100644 --- a/TODO.md +++ b/TODO.md @@ -54,10 +54,13 @@ Add and document the following new concepts: * Integrate discussions of SegWit into early parts of chapter 4. **6/23** * Write chapter 4.6 **6/23** 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). + * Research PSBTs **7/2** + * Update Outlines 13. Add Wallet Updates. * Bitcoin Descriptors **6/30** - * Show what a SegWit descriptor looks like + * Show what a SegWit descriptor looks like **7/2** * Show what a multi-sig descriptor looks like + * Revise based on comments * Key Ordering 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). From 578640295a23dbdf8cc9f1d0f47ca41d7309de8d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:00:23 -1000 Subject: [PATCH 171/202] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 7eae7da..fc52ed1 100644 --- a/TODO.md +++ b/TODO.md @@ -66,7 +66,7 @@ Add and document the following new concepts: ## 5. Finish Later Chapters -15. Write Tor Chapter. We want to fully integrate Tor into the installation of Bitcoin and then later talk about its usage. +15. Edit & Intregtrate Tor Chapter. 16. Write Lightning Chapters. We'd like to parallel the CLI introduction to Bitcoin with a similar CLI introduction to Lightning. 17. Edit & Integrate all "C" work 18. Edit & Integrate all "Other Languages" work From 5ae82e2a8ed059cf10aa0927dfc9fa7f0fb029ee Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:02:54 -1000 Subject: [PATCH 172/202] first cut of PSBT chapters --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd67a99..f909cd8 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,9 @@ _This tutorial assumes that you have some minimal background of how to use the c * [6.3: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) * [6.4: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) * [6.5: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) - + * [6.6: Creating a PSBT](06_6_Creating_a_PSBT.md) + * [6.7: Using a PSBT](06_7_Using_a-PSBT.md) + ## PART THREE: BITCOIN SCRIPTING **Status:** Requires editing; requires check that it works in 0.20; requires concepts brought up to 0.20. From 4da706586b559ab7223e23ae2657b9fea09981c3 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:04:26 -1000 Subject: [PATCH 173/202] edited new chapter names --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f909cd8..38b300e 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ _This tutorial assumes that you have some minimal background of how to use the c * [6.3: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) * [6.4: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) * [6.5: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) - * [6.6: Creating a PSBT](06_6_Creating_a_PSBT.md) - * [6.7: Using a PSBT](06_7_Using_a-PSBT.md) + * [6.6: Creating a Partially Signed Bitcoin Transaction](06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [6.7: Using a Partially Signed Bitcoin Transaction](06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md) ## PART THREE: BITCOIN SCRIPTING From 720142c1f21831ba7ef692fbbd30f8ff0f17cb10 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:14:36 -1000 Subject: [PATCH 174/202] initial outline --- ..._a_Partially_Signed_Bitcoin_Transaction.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md diff --git a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md new file mode 100644 index 0000000..ae3ac7b --- /dev/null +++ b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -0,0 +1,21 @@ +# 6.6: Creating a Partially Signed Bitcoin Transaction + +> :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. + +[intro] + +> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0 that had continued to be expanded through Bitcoin Core 0.20.0. Most of the commands in this section are from 0.17.0, but the updated `importmulti` that support descriptors is from 0.18.0. + +## Understand a PSBT + +## Create a PSBT the Old-Fashioned Way + +## Create a PSBT the Hard Way + +## Create a PSBT the Easy Way + +## Examine Your PSBT + +## Summary: Creating a Partially Signed Bitcoin Transaction + +## What's Next? From 9fb47b2f87c1c5c1c65c91febedc4971fdcd21cf Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:17:03 -1000 Subject: [PATCH 175/202] Update 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md --- 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md index ae3ac7b..f29d10f 100644 --- a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md +++ b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -4,7 +4,7 @@ [intro] -> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0 that had continued to be expanded through Bitcoin Core 0.20.0. Most of the commands in this section are from 0.17.0, but the updated `importmulti` that support descriptors is from 0.18.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 process (though they will still be able to recognize the final transaction). ## Understand a PSBT From 95f6f634845515265daeb3bd28a658e5549c38b0 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:20:12 -1000 Subject: [PATCH 176/202] initial outline --- ..._a_Partially_Signed_Bitcoin_Transaction.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md diff --git a/06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md b/06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md new file mode 100644 index 0000000..c062038 --- /dev/null +++ b/06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md @@ -0,0 +1,21 @@ +# 6.7: Using a Partially Signed Bitcoin Transaction + +> :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. + +[intro] + +> :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). + +## Use a PSBT to MultiSig + +## Use a PSBT to Pool Money + +## Use a PSBT to CoinJoin + +## Summary: Using a Partially Signed Bitcoin Transaction + +> :fire: ***What's the power of a PSBT?*** + +## What's Next? + +Move on to "Bitcoin Scripting" with [Chapter Seven: Introducing Bitcoin Scripts](07_0_Introducing_Bitcoin_Scripts.md). From 75b834f3b5d97536620154ae800f9c4bde5e747e Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:22:20 -1000 Subject: [PATCH 177/202] added new link forward --- 06_5_Sending_a_Transaction_with_Data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/06_5_Sending_a_Transaction_with_Data.md b/06_5_Sending_a_Transaction_with_Data.md index 0e4d6b2..4cbd367 100644 --- a/06_5_Sending_a_Transaction_with_Data.md +++ b/06_5_Sending_a_Transaction_with_Data.md @@ -120,4 +120,4 @@ Note that there is some controversy over using the Bitcoin blockchain in this wa ## What's Next? -Move on to "Bitcoin Scripting" with [Chapter Seven: Introducing Bitcoin Scripts](07_0_Introducing_Bitcoin_Scripts.md). +Continue "Expanding Bitcoin Transactions" with [§6.6: Creating a Partially Signed Bitcoin Transaction](06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md). From 6d8c4a541f902d3801d88b14e800fec536610721 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:23:10 -1000 Subject: [PATCH 178/202] added new link forward --- 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md index f29d10f..d25218b 100644 --- a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md +++ b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -19,3 +19,5 @@ ## Summary: Creating a Partially Signed Bitcoin Transaction ## What's Next? + +Continue "Expanding Bitcoin Transactions" with [§6.7: Using a Partially Signed Bitcoin Transaction](06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md). From fb5a51bcca690879f459fc2bb07fa8694c89116b Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:24:36 -1000 Subject: [PATCH 179/202] Update TODO.md --- TODO.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index fc52ed1..b3694d3 100644 --- a/TODO.md +++ b/TODO.md @@ -55,7 +55,9 @@ Add and document the following new concepts: * Write chapter 4.6 **6/23** 12. Add PSBT. Partially Signed Bitcoin Transactions are a powerful new interchange format that should be fully included in our discussions of multi-sigs and escrows (which instead fell back on older methodologies in v1.0). * Research PSBTs **7/2** - * Update Outlines + * Update Outlines **7/2** + * Write 6.6: Creating a PSBT + * Write 6.7: Using a PSBT 13. Add Wallet Updates. * Bitcoin Descriptors **6/30** * Show what a SegWit descriptor looks like **7/2** From adaad303f6a23ed8d0d753d54f39201c003cdc40 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:24:56 -1000 Subject: [PATCH 180/202] Added new topic --- 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md index d25218b..7e51c44 100644 --- a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md +++ b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -14,7 +14,9 @@ ## Create a PSBT the Easy Way -## Examine Your PSBT +## Examine a PSBT + +## Update a PSBT ## Summary: Creating a Partially Signed Bitcoin Transaction From 183263392a017b788db448d4a992af313374ff8b Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 11:25:15 -1000 Subject: [PATCH 181/202] added another new topic --- 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md index 7e51c44..12ff2e6 100644 --- a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md +++ b/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md @@ -18,6 +18,8 @@ ## Update a PSBT +## Sign a PSBT + ## Summary: Creating a Partially Signed Bitcoin Transaction ## What's Next? From b526dfddbe476432f7fa5083e247da83242ca032 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:30:06 -1000 Subject: [PATCH 182/202] first cut of info on ordering --- 06_1_Sending_a_Transaction_to_a_Multisig.md | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/06_1_Sending_a_Transaction_to_a_Multisig.md b/06_1_Sending_a_Transaction_to_a_Multisig.md index b928787..b7db170 100644 --- a/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -114,6 +114,35 @@ Here's an important caveat: nothing about your multisig is saved into your walle Technically, the `redeemScript` can be recreated by rerunning `createmultisig` with the complete list of public keys _in the same order_ and with the right m-of-n count. But, it's better to hold onto it and save yourself stress and grief. +### Watch the Order + +Here's one thing to be very wary of: _order matters_. The order of keys used to create a multi-sig creates a unique hash, which is to say if you put the key in a different order, they'll produce a different address, as shown: +``` +$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "2NFBQvz57UzKWDr2Vx5D667epVZifjGixkm", + "redeemScript": "52210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0321039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b352ae", + "descriptor": "sh(multi(2,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3))#8l6hvjsk" +} +standup@btctest20:~$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey2'","'$pubkey1'"]''' +{ + "address": "2N5bC4Yc5Pqept1y8nPRqvWmFSejkVeRb1k", + "redeemScript": "5221039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0352ae", + "descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg" +} +``` +More notably, each ordering creates a different _redeemScript_. That means that if you used these basic techniques and failed to save the redeemScript as you were instructed, you'll have to walk through an ever-increasing number of variations to find the right one when you try and Spend your funds! + +[BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) suggests a way to lexicographically order keys, so that they always generate the same multisignatures. ColdCard and Electrum are among the wallets that already support this. Of course, this can cause troubles on its own if you don't know if a multisig address was created with sorted or unsorted keys. Once more, [descriptors](03_5_Understanding_the_Descriptor.md) come to the rescue. If a multisig is unsorted, it's built with the function `multi` and if it's sorted it's built with the function `sortedmulti`. + +If you look at the `desc`riptor for the multisig, above, you'll see that Bitcoin Core doesn't currently create sorted multisigs: +``` + "desc": "wpkh([fe6f2292/0'/0'/1']02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3)#zc64l8dw", +``` +However, if it imports an address with type `multisort`, it'll do the right thing, which is the whole point of descriptors! + +> :warning: **VERSION WARNING:** Bitcoin Core only understands the `sortedmulti` descriptor function beginning with v 0.20.0. Try and access the descriptor on an earlier version of Bitcoin Core and you'll get an error like "A function is needed within P2WSH". + ## Send to a Multisig Address If you've got a multisignature in a convenient P2SH format, like the one generated by `bitcoin-cli`, it can be sent to exactly like a normal address. From 7839ac62d164a306b2e879464f5910dc04d8a287 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:34:20 -1000 Subject: [PATCH 183/202] cleaned up new sortedmulti section --- 06_1_Sending_a_Transaction_to_a_Multisig.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/06_1_Sending_a_Transaction_to_a_Multisig.md b/06_1_Sending_a_Transaction_to_a_Multisig.md index b7db170..ac5e708 100644 --- a/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -116,7 +116,7 @@ Technically, the `redeemScript` can be recreated by rerunning `createmultisig` w ### Watch the Order -Here's one thing to be very wary of: _order matters_. The order of keys used to create a multi-sig creates a unique hash, which is to say if you put the key in a different order, they'll produce a different address, as shown: +Here's one thing to be very wary of: _order matters_. The order of keys used to create a multi-sig creates a unique hash, which is to say if you put the keys in a different order, they'll produce a different address, as shown: ``` $ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' { @@ -131,15 +131,15 @@ standup@btctest20:~$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$p "descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg" } ``` -More notably, each ordering creates a different _redeemScript_. That means that if you used these basic techniques and failed to save the redeemScript as you were instructed, you'll have to walk through an ever-increasing number of variations to find the right one when you try and Spend your funds! +More notably, each ordering creates a different _redeemScript_. That means that if you used these basic techniques and failed to save the redeemScript as you were instructed, you'll have to walk through an ever-increasing number of variations to find the right one when you try and spend your funds! [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) suggests a way to lexicographically order keys, so that they always generate the same multisignatures. ColdCard and Electrum are among the wallets that already support this. Of course, this can cause troubles on its own if you don't know if a multisig address was created with sorted or unsorted keys. Once more, [descriptors](03_5_Understanding_the_Descriptor.md) come to the rescue. If a multisig is unsorted, it's built with the function `multi` and if it's sorted it's built with the function `sortedmulti`. -If you look at the `desc`riptor for the multisig, above, you'll see that Bitcoin Core doesn't currently create sorted multisigs: +If you look at the `desc`riptor for the multisig that you created above, you'll see that Bitcoin Core doesn't currently create sort its multisigs: ``` - "desc": "wpkh([fe6f2292/0'/0'/1']02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3)#zc64l8dw", + "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" ``` -However, if it imports an address with type `multisort`, it'll do the right thing, which is the whole point of descriptors! +However, if it imports an address with type `sortedmulti`, it'll do the right thing, which is the whole point of descriptors! > :warning: **VERSION WARNING:** Bitcoin Core only understands the `sortedmulti` descriptor function beginning with v 0.20.0. Try and access the descriptor on an earlier version of Bitcoin Core and you'll get an error like "A function is needed within P2WSH". From 33f068cc4fdf6e7e6a2b1eb2a8ae4a915c73d290 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:37:23 -1000 Subject: [PATCH 184/202] updated multisig link --- 03_5_Understanding_the_Descriptor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03_5_Understanding_the_Descriptor.md b/03_5_Understanding_the_Descriptor.md index c4988d6..7d43fe7 100644 --- a/03_5_Understanding_the_Descriptor.md +++ b/03_5_Understanding_the_Descriptor.md @@ -10,7 +10,7 @@ You may have noticed a weird `desc:` field in the `listunspent` command of the p Most of this course presumes that you're working entirely from a single node where you manage your own wallet, sending and receiving payments with the addresses created by that wallet. However, that's not necessarily how the larger Bitcoin ecosystem works. There, you're more likely to be moving addresses between wallets and even setting up wallets to watch over funds controlled by different wallets. -That's where descriptors come in. They're most useful if you're interacting with software _other_ than Bitcoin Core, and really need to lean on this sort of compatibility function, but we'll also use a tiny bit of what we learned here in [§6.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_3_Sending_an_Automated_Multisig.md). +That's where descriptors come in. They're most useful if you're interacting with software _other_ than Bitcoin Core, and really need to lean on this sort of compatibility function: see [§6.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/06_1_Sending_a_Transaction_to_a_Multisig.md) for a real-world example of how having the capability of descriptors is critical. Moving addresses between wallets used to focus on `xpub` and `xprv`, and those are still supported. From d0eaa83cd43fe789ccf22b8d21da0277b0f58d55 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:38:43 -1000 Subject: [PATCH 185/202] Update TODO.md --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index b3694d3..8923686 100644 --- a/TODO.md +++ b/TODO.md @@ -61,9 +61,9 @@ Add and document the following new concepts: 13. Add Wallet Updates. * Bitcoin Descriptors **6/30** * Show what a SegWit descriptor looks like **7/2** - * Show what a multi-sig descriptor looks like + * Show what a multi-sig descriptor looks like **7/2** * Revise based on comments - * Key Ordering + * Key Ordering (sortedmulti) **7/2** **Partially Supported in 0.20** 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). ## 5. Finish Later Chapters From 0d2cfcc929112c7681e4d3c4675e109e1ed499a1 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:40:07 -1000 Subject: [PATCH 186/202] Update TODO.md --- TODO.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/TODO.md b/TODO.md index 8923686..5d40c8e 100644 --- a/TODO.md +++ b/TODO.md @@ -65,16 +65,17 @@ Add and document the following new concepts: * Revise based on comments * Key Ordering (sortedmulti) **7/2** **Partially Supported in 0.20** 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). +15. Consider splitting up Chapter 6 (definitely if we get an HWI chapter) ## 5. Finish Later Chapters -15. Edit & Intregtrate Tor Chapter. -16. Write Lightning Chapters. We'd like to parallel the CLI introduction to Bitcoin with a similar CLI introduction to Lightning. -17. Edit & Integrate all "C" work -18. Edit & Integrate all "Other Languages" work -19. Edit & Integrate Appendices work -20. Write or request Lightning/C chapter +16. Edit & Intregtrate Tor Chapter. +17. Write Lightning Chapters. We'd like to parallel the CLI introduction to Bitcoin with a similar CLI introduction to Lightning. +18. Edit & Integrate all "C" work +19. Edit & Integrate all "Other Languages" work +20. Edit & Integrate Appendices work +21. Write or request Lightning/C chapter ## 6. Finalize Book -21. Re-edit everything +22. Re-edit everything From 5ff1d52bed33a6a22e066467175de4b964812e5a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:51:14 -1000 Subject: [PATCH 187/202] big reordering for PSBT split --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 38b300e..42751eb 100644 --- a/README.md +++ b/README.md @@ -45,18 +45,21 @@ _This tutorial assumes that you have some minimal background of how to use the c * [5.1 Watching for Stuck Transactions](05_1_Watching_for_Stuck_Transactions.md) * [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](06_0_Expanding_Bitcoin_Transactions.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.3: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) - * [6.4: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) - * [6.5: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) - * [6.6: Creating a Partially Signed Bitcoin Transaction](06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md) - * [6.7: Using a Partially Signed Bitcoin Transaction](06_7_Using_a_Partially_Signed_Bitcoin_Transaction.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) + * [7.2: Using a Partially Signed Bitcoin Transaction](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.3: Integrating with Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md) +* [8.0: Expanding Bitcoin Transactions in Other Ways](08_0_Expanding_Bitcoin_Transactions_Other.md) + * [8_1: Sending a Transaction with a Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [8.5: Sending a Transaction with Data](08_2_Sending_a_Transaction_with_Data.md) ## PART THREE: BITCOIN SCRIPTING -**Status:** Requires editing; requires check that it works in 0.20; requires concepts brought up to 0.20. +**Status:** Requires renumbering; requires editing; requires check that it works in 0.20; requires concepts brought up to 0.20. * [7.0: Introducing Bitcoin Scripts](07_0_Introducing_Bitcoin_Scripts.md) * [7.1: Understanding the Foundation of Transactions](07_1_Understanding_the_Foundation_of_Transactions.md) @@ -83,7 +86,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART FOUR: USING TOR -**Status:** Unwritten. +**Status:** Requires renumbering; Unwritten. * [12.0: Using Tor](12_0_Using_Tor.md) * 12.1: Verifying Your Tor Setup @@ -92,7 +95,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART FIVE: USING LIGHTNING-CLI -**Status:** Unwritten. Chapter 14 may expand into multiple chapters. +**Status:** Requires renumbering; Unwritten. Chapter 14 may expand into multiple chapters. (At this point, I'm assuming that Lightning will be integrated into Standup, at which point we just need to tech how to use it at a pretty basic level.) @@ -108,7 +111,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART SIX: PROGRAMMING WITH RPC -**Status:** This section is currently a messy set of older writings which are being reorganized as listed below. We're not going to work through this section until we've got chapters 1-11 updated per our current notes, then 12-14 written. But, if you'd like to see what we have to date on programming in correlation with Bitcoin Core, please feel free. +**Status:** Requires renumbering; This section is currently a messy set of older writings which are being reorganized as listed below. We're not going to work through this section until we've got chapters 1-11 updated per our current notes, then 12-14 written. But, if you'd like to see what we have to date on programming in correlation with Bitcoin Core, please feel free. * [15.0: Talking to Bitcoind with C](15_0_Talking_to_Bitcoind.md) — Needs Rewrite + Editing * [15.1: Accessing Bitcoind with C](15_1_Accessing_Bitcoind_with_C.md) — Needs Rewrite From 1867c27e6a978c5da167c9a5afc579e16635f0c5 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:51:50 -1000 Subject: [PATCH 188/202] fixed some numbering --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 42751eb..50b7b67 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,8 @@ _This tutorial assumes that you have some minimal background of how to use the c * [7.2: Using a Partially Signed Bitcoin Transaction](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) * [7.3: Integrating with Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md) * [8.0: Expanding Bitcoin Transactions in Other Ways](08_0_Expanding_Bitcoin_Transactions_Other.md) - * [8_1: Sending a Transaction with a Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) - * [8.5: Sending a Transaction with Data](08_2_Sending_a_Transaction_with_Data.md) + * [8.1: Sending a Transaction with a Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [8.2: Sending a Transaction with Data](08_2_Sending_a_Transaction_with_Data.md) ## PART THREE: BITCOIN SCRIPTING From ff0fe4e81c227d31fcc157bec43aeda80baa659d Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 12:57:58 -1000 Subject: [PATCH 189/202] Update TODO.md --- TODO.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 5d40c8e..caee72d 100644 --- a/TODO.md +++ b/TODO.md @@ -66,7 +66,8 @@ Add and document the following new concepts: * Key Ordering (sortedmulti) **7/2** **Partially Supported in 0.20** 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). 15. Consider splitting up Chapter 6 (definitely if we get an HWI chapter) - + * Rearrange all early files and links + ## 5. Finish Later Chapters 16. Edit & Intregtrate Tor Chapter. From 8c564c8baab46bd450d409b7d6e2f643b01a6200 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 13:04:24 -1000 Subject: [PATCH 190/202] various renumbering of files --- ...xpanding_Bitcoin_Transactions_Multisigs.md | 0 07_0_Expanding_Bitcoin_Transactions_PSBTs.md | 27 +++++++++++++++++++ ..._a_Partially_Signed_Bitcoin_Transaction.md | 0 ..._a_Partially_Signed_Bitcoin_Transaction.md | 0 07_3_Integrating_with_Hardware_Wallets.md | 21 +++++++++++++++ 08_0_Expanding_Bitcoin_Transactions_Other.md | 27 +++++++++++++++++++ ...1_Sending_a_Transaction_with_a_Locktime.md | 0 ...=> 08_2_Sending_a_Transaction_with_Data.md | 0 8 files changed, 75 insertions(+) rename 06_0_Expanding_Bitcoin_Transactions.md => 06_0_Expanding_Bitcoin_Transactions_Multisigs.md (100%) create mode 100644 07_0_Expanding_Bitcoin_Transactions_PSBTs.md rename 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md => 07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md (100%) rename 06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md => 07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md (100%) create mode 100644 07_3_Integrating_with_Hardware_Wallets.md create mode 100644 08_0_Expanding_Bitcoin_Transactions_Other.md rename 06_4_Sending_a_Transaction_with_a_Locktime.md => 08_1_Sending_a_Transaction_with_a_Locktime.md (100%) rename 06_5_Sending_a_Transaction_with_Data.md => 08_2_Sending_a_Transaction_with_Data.md (100%) diff --git a/06_0_Expanding_Bitcoin_Transactions.md b/06_0_Expanding_Bitcoin_Transactions_Multisigs.md similarity index 100% rename from 06_0_Expanding_Bitcoin_Transactions.md rename to 06_0_Expanding_Bitcoin_Transactions_Multisigs.md diff --git a/07_0_Expanding_Bitcoin_Transactions_PSBTs.md b/07_0_Expanding_Bitcoin_Transactions_PSBTs.md new file mode 100644 index 0000000..59fc82c --- /dev/null +++ b/07_0_Expanding_Bitcoin_Transactions_PSBTs.md @@ -0,0 +1,27 @@ +# Chapter Six: Expanding Bitcoin Transactions + +Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit recipient; (3) immediately. However, all three parts of this definition can be expanded using more complex Bitcoin transactions, which can alternatively send data, which can send to a group of recipients, or which can send at a later time. These three options represent further empowerment of Bitcoin and also the furthest boundaries of what you can do with the basic `bitcoin-cli` command. + +## Objectives for This Section + +After working through this chapter, a developer will be able to: + + * Create Multisignature Bitcoin Addresses + * Create Transactions with Locktimes + * Create Transactions with Data + +Supporting objectives include the ability to: + + * Understand How to Spend Funds Sent to a Multisignature + * Plan for the Power of Multisignatures + * Understand the Different Sorts of Timelocks + * Plan for the Power of Locktime + * Plan for the Power of OP_RETURN + +## Table of Contents + + * [Section One: Sending a Transaction with a Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [Section Two: Spending a Transaction with a Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [Section Three: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) + * [Section Four: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) + * [Section Five: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) diff --git a/06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md b/07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md similarity index 100% rename from 06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md rename to 07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md diff --git a/06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md b/07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md similarity index 100% rename from 06_7_Using_a_Partially_Signed_Bitcoin_Transaction.md rename to 07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md diff --git a/07_3_Integrating_with_Hardware_Wallets.md b/07_3_Integrating_with_Hardware_Wallets.md new file mode 100644 index 0000000..c062038 --- /dev/null +++ b/07_3_Integrating_with_Hardware_Wallets.md @@ -0,0 +1,21 @@ +# 6.7: Using a Partially Signed Bitcoin Transaction + +> :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. + +[intro] + +> :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). + +## Use a PSBT to MultiSig + +## Use a PSBT to Pool Money + +## Use a PSBT to CoinJoin + +## Summary: Using a Partially Signed Bitcoin Transaction + +> :fire: ***What's the power of a PSBT?*** + +## What's Next? + +Move on to "Bitcoin Scripting" with [Chapter Seven: Introducing Bitcoin Scripts](07_0_Introducing_Bitcoin_Scripts.md). diff --git a/08_0_Expanding_Bitcoin_Transactions_Other.md b/08_0_Expanding_Bitcoin_Transactions_Other.md new file mode 100644 index 0000000..59fc82c --- /dev/null +++ b/08_0_Expanding_Bitcoin_Transactions_Other.md @@ -0,0 +1,27 @@ +# Chapter Six: Expanding Bitcoin Transactions + +Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit recipient; (3) immediately. However, all three parts of this definition can be expanded using more complex Bitcoin transactions, which can alternatively send data, which can send to a group of recipients, or which can send at a later time. These three options represent further empowerment of Bitcoin and also the furthest boundaries of what you can do with the basic `bitcoin-cli` command. + +## Objectives for This Section + +After working through this chapter, a developer will be able to: + + * Create Multisignature Bitcoin Addresses + * Create Transactions with Locktimes + * Create Transactions with Data + +Supporting objectives include the ability to: + + * Understand How to Spend Funds Sent to a Multisignature + * Plan for the Power of Multisignatures + * Understand the Different Sorts of Timelocks + * Plan for the Power of Locktime + * Plan for the Power of OP_RETURN + +## Table of Contents + + * [Section One: Sending a Transaction with a Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [Section Two: Spending a Transaction with a Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [Section Three: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) + * [Section Four: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) + * [Section Five: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) diff --git a/06_4_Sending_a_Transaction_with_a_Locktime.md b/08_1_Sending_a_Transaction_with_a_Locktime.md similarity index 100% rename from 06_4_Sending_a_Transaction_with_a_Locktime.md rename to 08_1_Sending_a_Transaction_with_a_Locktime.md diff --git a/06_5_Sending_a_Transaction_with_Data.md b/08_2_Sending_a_Transaction_with_Data.md similarity index 100% rename from 06_5_Sending_a_Transaction_with_Data.md rename to 08_2_Sending_a_Transaction_with_Data.md From a483951c98a7c95fbaaa90043b8c5e16608e3062 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 13:09:54 -1000 Subject: [PATCH 191/202] updated for new chapter structure --- 06_0_Expanding_Bitcoin_Transactions_Multisigs.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/06_0_Expanding_Bitcoin_Transactions_Multisigs.md b/06_0_Expanding_Bitcoin_Transactions_Multisigs.md index 59fc82c..10896d6 100644 --- a/06_0_Expanding_Bitcoin_Transactions_Multisigs.md +++ b/06_0_Expanding_Bitcoin_Transactions_Multisigs.md @@ -1,27 +1,21 @@ -# Chapter Six: Expanding Bitcoin Transactions +# Chapter Six: Expanding Bitcoin Transactions with Multisigs. -Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit recipient; (3) immediately. However, all three parts of this definition can be expanded using more complex Bitcoin transactions, which can alternatively send data, which can send to a group of recipients, or which can send at a later time. These three options represent further empowerment of Bitcoin and also the furthest boundaries of what you can do with the basic `bitcoin-cli` command. +Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit recipient; (3) from a single machine; (4) immediately. However, all four parts of this definition can be expanded using more complex Bitcoin transactions. This first chapter on "Expansion" shows how to vary points (2) and (3), by sending money to an address that represents multiple recipients (or at least, multiple signers). ## Objectives for This Section After working through this chapter, a developer will be able to: - * Create Multisignature Bitcoin Addresses - * Create Transactions with Locktimes - * Create Transactions with Data + * Create Multisignature Bitcoin Addresses Using Bitcoin Fundamentals + * Create Multisignature Bitcoin Addresses Using Easiser Mechanisms Supporting objectives include the ability to: * Understand How to Spend Funds Sent to a Multisignature * Plan for the Power of Multisignatures - * Understand the Different Sorts of Timelocks - * Plan for the Power of Locktime - * Plan for the Power of OP_RETURN ## Table of Contents * [Section One: Sending a Transaction with a Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) * [Section Two: Spending a Transaction with a Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) * [Section Three: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) - * [Section Four: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) - * [Section Five: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) From e4fd9a301a78e30c101a51166b047b80f52db82a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 13:10:58 -1000 Subject: [PATCH 192/202] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50b7b67..8682312 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ _This tutorial assumes that you have some minimal background of how to use the c ### PART TWO: USING BITCOIN-CLI -**Status:** Needs new content on (1) PSBTs; (2) sorted multisigs; and (3) if appropriate HWI. Also needs a little integration of descriptors in later chapters (3.5, 6.2+) +**Status:** The PSBT and HWI content (chapter 6) is new, and so still being written. * [3.0: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md) * [3.1: Verifying Your Bitcoin Setup](03_1_Verifying_Your_Bitcoin_Setup.md) From 5403239d0d3b06ec07dbba91cc5685979d40b9ce Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 13:11:27 -1000 Subject: [PATCH 193/202] updated chapter link --- 05_3_Funding_a_Transaction_with_CPFP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_3_Funding_a_Transaction_with_CPFP.md b/05_3_Funding_a_Transaction_with_CPFP.md index 8417912..3b3e3b0 100644 --- a/05_3_Funding_a_Transaction_with_CPFP.md +++ b/05_3_Funding_a_Transaction_with_CPFP.md @@ -126,4 +126,4 @@ You can take advantage of the CPFP incentives to free up funds that have been se ## What's Next? -Advance through "bitcoin-cli" with [Chapter Six: Expanding Bitcoin Transactions](06_0_Expanding_Bitcoin_Transactions.md). +Advance through "bitcoin-cli" with [Chapter Six: Expanding Bitcoin Transactions with Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md). From bb9ce2447b89b9abe48de1c4cdc507fbd5d2abea Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 13:12:09 -1000 Subject: [PATCH 194/202] Update 06_3_Sending_an_Automated_Multisig.md --- 06_3_Sending_an_Automated_Multisig.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/06_3_Sending_an_Automated_Multisig.md b/06_3_Sending_an_Automated_Multisig.md index 510f0c5..7f0cc61 100644 --- a/06_3_Sending_an_Automated_Multisig.md +++ b/06_3_Sending_an_Automated_Multisig.md @@ -120,4 +120,4 @@ There's an easier way to resepend funds sent to multisig addresses that simply r ## What's Next? -Continue "Expanding Bitcoin Transactions" with [§6.4: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md). +Advance through "bitcoin-cli" with [Chapter Seven: Expanding Bitcoin Transactions with PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). From e9db8cb298956d078e04d415e6c15e61a7e09514 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 14:12:21 -1000 Subject: [PATCH 195/202] more credits --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8682312..089c62d 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ Additional contributions are listed below: | Role | Names | | ------------------- | ---------------------------------------- | -| ***Contributors:*** | [gorazdko](https://github.com/gorazdko) (Rust section), [Javier Vargas](https://github.com/javiervargas) (C, Java, Tor sections), [jodobear](https://github.com/jodobear) (Appendix I, 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, Tor sections), [jodobear](https://github.com/jodobear) (Appendix I, Python section) | | ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) | | ***Sponsors:*** | Blockstream Corporation | From ac1632cd0467e7201ea1d733845ab3793f81bb1a Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 14:14:13 -1000 Subject: [PATCH 196/202] updated for new toc --- 08_0_Expanding_Bitcoin_Transactions_Other.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/08_0_Expanding_Bitcoin_Transactions_Other.md b/08_0_Expanding_Bitcoin_Transactions_Other.md index 59fc82c..62925f1 100644 --- a/08_0_Expanding_Bitcoin_Transactions_Other.md +++ b/08_0_Expanding_Bitcoin_Transactions_Other.md @@ -1,27 +1,21 @@ -# Chapter Six: Expanding Bitcoin Transactions +# Chapter Eight: Expanding Bitcoin Transactions in Other Ways -Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit recipient; (3) immediately. However, all three parts of this definition can be expanded using more complex Bitcoin transactions, which can alternatively send data, which can send to a group of recipients, or which can send at a later time. These three options represent further empowerment of Bitcoin and also the furthest boundaries of what you can do with the basic `bitcoin-cli` command. +The definition of basic transactions back in [Chapter Six](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) said that they sent _funds_ _immediately_, but that's another thing that can be changed. This final section on Expanding Bitcoin Transactions talks about how to send things other than cash and how to do it at a time other than now. ## Objectives for This Section After working through this chapter, a developer will be able to: - * Create Multisignature Bitcoin Addresses * Create Transactions with Locktimes * Create Transactions with Data Supporting objectives include the ability to: - * Understand How to Spend Funds Sent to a Multisignature - * Plan for the Power of Multisignatures * Understand the Different Sorts of Timelocks * Plan for the Power of Locktime * Plan for the Power of OP_RETURN ## Table of Contents - * [Section One: Sending a Transaction with a Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) - * [Section Two: Spending a Transaction with a Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) - * [Section Three: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md) - * [Section Four: Sending a Transaction with a Locktime](06_4_Sending_a_Transaction_with_a_Locktime.md) - * [Section Five: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md) + * [Section One: Sending a Transaction with a Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [Section Two: Sending a Transaction with Data](08_2_Sending_a_Transaction_with_Data.md) From 85cffe6d54f45f59a7495d42a57c0fd239c4c7cc Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 14:14:48 -1000 Subject: [PATCH 197/202] updated for new toc --- 08_1_Sending_a_Transaction_with_a_Locktime.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/08_1_Sending_a_Transaction_with_a_Locktime.md b/08_1_Sending_a_Transaction_with_a_Locktime.md index 2a3ebd6..2b730c5 100644 --- a/08_1_Sending_a_Transaction_with_a_Locktime.md +++ b/08_1_Sending_a_Transaction_with_a_Locktime.md @@ -1,4 +1,4 @@ -# 6.4: Sending a Transaction with a Locktime +8.1: Sending a Transaction with a Locktime > :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. @@ -134,4 +134,4 @@ Locktime offers a way to create a transaction that _should_ not be relayable to ## What's Next? -Continue "Expanding Bitcoin Transactions" with [§6.5: Sending a Transaction with Data](06_5_Sending_a_Transaction_with_Data.md). +Continue "Expanding Bitcoin Transactions" with [§8.2: Sending a Transaction with Data](08.2_Sending_a_Transaction_with_Data.md). From 8e4602d390c972dd808968da4bd292e4a6b5b391 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 14:15:05 -1000 Subject: [PATCH 198/202] replaced # --- 08_1_Sending_a_Transaction_with_a_Locktime.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/08_1_Sending_a_Transaction_with_a_Locktime.md b/08_1_Sending_a_Transaction_with_a_Locktime.md index 2b730c5..8f4f523 100644 --- a/08_1_Sending_a_Transaction_with_a_Locktime.md +++ b/08_1_Sending_a_Transaction_with_a_Locktime.md @@ -1,4 +1,4 @@ -8.1: Sending a Transaction with a Locktime +# 8.1: Sending a Transaction with a Locktime > :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. From 974bfef7bb0a4f966399bab1bc8bbd8474be1a75 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 14:16:19 -1000 Subject: [PATCH 199/202] Update 08_2_Sending_a_Transaction_with_Data.md --- 08_2_Sending_a_Transaction_with_Data.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/08_2_Sending_a_Transaction_with_Data.md b/08_2_Sending_a_Transaction_with_Data.md index 4cbd367..2827a52 100644 --- a/08_2_Sending_a_Transaction_with_Data.md +++ b/08_2_Sending_a_Transaction_with_Data.md @@ -1,4 +1,4 @@ -# 6.5: Sending a Transaction with Data +# 8.2: Sending a Transaction with Data > :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. @@ -120,4 +120,4 @@ Note that there is some controversy over using the Bitcoin blockchain in this wa ## What's Next? -Continue "Expanding Bitcoin Transactions" with [§6.6: Creating a Partially Signed Bitcoin Transaction](06_6_Creating_a_Partially_Signed_Bitcoin_Transaction.md). +Move on to "Bitcoin Scripting" with [Chapter Seven: Introducing Bitcoin Scripts](07_0_Introducing_Bitcoin_Scripts.md). From f6465d1a81e27033fac643417bf68bd7872e26d7 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 14:17:58 -1000 Subject: [PATCH 200/202] Update TODO.md --- TODO.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index caee72d..1f8c108 100644 --- a/TODO.md +++ b/TODO.md @@ -66,7 +66,11 @@ Add and document the following new concepts: * Key Ordering (sortedmulti) **7/2** **Partially Supported in 0.20** 14. Consider HWI. We need to investigate the Hardware Wallet Interface, which uses PSBTs with hardware wallets, and see if it's something we should include (and if our readers want us to). 15. Consider splitting up Chapter 6 (definitely if we get an HWI chapter) - * Rearrange all early files and links + * Break apart Chapter 6 **7/2** + * Rewrite all section links in early chapters (1-5, 6, 8) + * Update Script Chapters + * Update Tor Chapter + * Update Programming Chapters ## 5. Finish Later Chapters From 81ea70c735543606d5499bc4ac96a9d514d99798 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 15:02:24 -1000 Subject: [PATCH 201/202] Update 07_3_Integrating_with_Hardware_Wallets.md --- 07_3_Integrating_with_Hardware_Wallets.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/07_3_Integrating_with_Hardware_Wallets.md b/07_3_Integrating_with_Hardware_Wallets.md index c062038..587f94f 100644 --- a/07_3_Integrating_with_Hardware_Wallets.md +++ b/07_3_Integrating_with_Hardware_Wallets.md @@ -1,4 +1,4 @@ -# 6.7: Using a Partially Signed Bitcoin Transaction +# 7.3: Integrating with Hardware Wallets > :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. @@ -6,15 +6,15 @@ > :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). -## Use a PSBT to MultiSig +## Link to a Ledger -## Use a PSBT to Pool Money +## Import Addresses -## Use a PSBT to CoinJoin +## Create a Transaction with PSBT -## Summary: Using a Partially Signed Bitcoin Transaction +## Summary: Integrating with Hardware Wallets -> :fire: ***What's the power of a PSBT?*** +> :fire: ***What's the power of HWI?*** ## What's Next? From 97da298926120c55eae47b5d4e4ee78ea1384a2e Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Thu, 2 Jul 2020 15:31:10 -1000 Subject: [PATCH 202/202] A few clarifications --- 03_5_Understanding_the_Descriptor.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/03_5_Understanding_the_Descriptor.md b/03_5_Understanding_the_Descriptor.md index 7d43fe7..dce872d 100644 --- a/03_5_Understanding_the_Descriptor.md +++ b/03_5_Understanding_the_Descriptor.md @@ -67,6 +67,7 @@ function([derivation-path]key)#checksum Here's what that all means: * **Function.** The function that is used to create an address from that key. In this cases it's `pkh`, which is the standard P2PKH legacy address that you met in [§3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). Similarly, a P2WSH SegWit address would use `wsh` and a P2WPKH address would use `wpkh`. * **Derivation Path.** This describes what part of an HD wallet is being exported. In this case it's a seed with the fingerprint `d6043800` and then the 18th child of the 0th child of the 0th child (`0'/0'/18'`) of that seed. There may also be a further derivation after the key: `function([derivation-path]key/more-derivation)#checksum` + * It's worth noting here that if you ever get a derivation path without a fingerprint, you can make it up. It's just that if there's an existing one, you should match it, because if you ever go back to the device that created the fingerprint, you'll need to have the same one. * **Key**. The key or keys that are being transferred. This could be something traditional like an `xpub` or `xprv`, it could just be a public key for an address as in this case, it could be a set of addresses for a multi-signature, or it could be something else. This is the core data: the function explains what to do with it. * **Checksum**. Descriptors are meant to be human transferrable. This checksum makes sure you got it right. @@ -118,7 +119,7 @@ remote$ bitcoin-cli importmulti '[{"desc": "pkh([d6043800/0'"'"'/0'"'"'/18'"'"'] } ] ``` -First, you'll note our first really ugly use of quotes. Every `'` in the derivation path had to be replaced with `'"'"'`. Just expect to have to do that if you're manipulating a descriptor that contains a derivation path. +First, you'll note our first really ugly use of quotes. Every `'` in the derivation path had to be replaced with `'"'"'`. Just expect to have to do that if you're manipulating a descriptor that contains a derivation path. (The other option is to exchange the `'` with a `h` for hardened, but that will change you checksum, so if you prefer that for its ease of use, you'll need to get a new checksum with `getdescriptorinfo`.) Second, you'll note that we flagged this as `watchonly`. That's because we know that it's a public key, so we can't spend with it. If we'd failed to enter this flag, `importmulti` would helpfully have told us something like: `Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.`.