From d9ab35668c34324c561003ff32722f803d451b84 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Mon, 3 Apr 2017 17:05:09 -0700 Subject: [PATCH] Update 4_4_Sending_Coins_with_a_Raw_Transaction.md --- 4_4_Sending_Coins_with_a_Raw_Transaction.md | 92 +++++++++++---------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/4_4_Sending_Coins_with_a_Raw_Transaction.md b/4_4_Sending_Coins_with_a_Raw_Transaction.md index a797e9e..22a5b11 100644 --- a/4_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/4_4_Sending_Coins_with_a_Raw_Transaction.md @@ -1,75 +1,79 @@ +# 4.4: Sending Coins with Raw Transactions + +> **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. + +As we said, the `bitcoin-cli` offers three major ways to send coins. Section 4.1 talking about sending them with the `sendtoaddress` command. Since then, we've been building details on how to send coins a second way, with raw transactions. Section 4.2 taught how to create a raw transaction, an Interlude taught how to use JQ, and Section 4.3 taught how to use named arguments. + +We can now put those together and actually send cash using a raw transaction. ## Create a Change Address -Our first raw transaction 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 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 create a change address: ``` $ changeaddress=$(bitcoin-cli getrawchangeaddress) $ echo $changeaddress -mxU9cmhJfkKWDtBspHaA36LkeafEDeaogJ +myrK8U3SE1nWh9y9XPho5aTrKYW6n8qSQv ``` Note that this is 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. -You now have an additional address inside your wallet that you can use to receive change from a UTXO! +You now have an additional address inside your wallet, so that you can use to receive change from a UTXO! In order to use it, you'll need to create a raw transaction with two outputs. +## Pick Sufficient UTXOs -## Write a Raw Transaction with Two Outputs +Our simple raw transaction was simple in another way: it assumed that there was enough money in a single UTXO to cover the transaction. However, you'll often want create transactions that expend more money than is in a single UTXO. To do this, you must create a raw transaction with two (or more) inputs. -You're now ready to write a more complex raw transaction. It will be based on the two unspent UTXOs still in our wallet: +## Write a Real Raw Transaction + +To summarize: creating a real raw transaction to send coins will often require multiple inputs and will almost always require multiple outputs, one of which is a change address. + +Here's the transactions we'll be using in this example: ``` $ bitcoin-cli listunspent [ { - "txid": "c1abb6951e6a9aae7e384412b69b69e59c10daac9397d01d0c52b7bc6278d589", - "vout": 1, - "address": "mygxipnJUsBgFvscKAaoxDdE8aCmHhRfTZ", + "txid": "ec0598918f6f5476cb90365651e8a2724ef26f949290bbf196f41ed96092a52f", + "vout": 0, + "address": "mjtEqr4Fffd1XtpAkKoDkMBP54mMXJeQ3j", "account": "", - "scriptPubKey": "76a914c756c7bd67bf83d83c04e3dc6fd1ff0c6fe8ea9888ac", - "amount": 0.07800000, - "confirmations": 237, + "scriptPubKey": "76a9142fe70d51e886b9ef73b76c1743c5a2bb2894db8588ac", + "amount": 3.90000000, + "confirmations": 9551, "spendable": true, "solvable": true }, { - "txid": "ab7ca727055b812df882298f4e6e10ec699fb6250d843c813623171781f896d8", + "txid": "3470e5fe08633583d136b9cd49bb1a224c9d9313a0b4584fd3b7438dbdf34dbd", "vout": 0, - "address": "mygxipnJUsBgFvscKAaoxDdE8aCmHhRfTZ", + "address": "msiyutru5TV33Q2UGK2Bbh2ewdrYALBzTb", "account": "", - "scriptPubKey": "76a914c756c7bd67bf83d83c04e3dc6fd1ff0c6fe8ea9888ac", - "amount": 0.07800000, - "confirmations": 237, + "scriptPubKey": "76a91485e7d9fe99708d575f3b93be13c0c55c6ffb765088ac", + "amount": 1.95000000, + "confirmations": 9542, "spendable": true, "solvable": true } ] + ``` -We want to send 0.1 BTC back to the TP faucet. This requires combining our two UTXOs, because neither contains quite that amount of bitcoin. It also requires sending to two addresses: one for the TP faucet (n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi) and one as a change address (mxU9cmhJfkKWDtBspHaA36LkeafEDeaogJ). In other words, we're going to have two inputs and two outputs in our raw transaction. +In this example we need to send 4.0 BTC, which is larger than either of our UTXOs. This requires combining them, then using our change address to get the unspent funds. ### Set Up Your Variables We've already have `$changeaddress` and `$recipient` variables from our previous examples: ``` $ echo $changeaddress -mxU9cmhJfkKWDtBspHaA36LkeafEDeaogJ -$ echo $recipient +myrK8U3SE1nWh9y9XPho5aTrKYW6n8qSQv +~$ echo $recipient n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi ``` We also need to record the txid and vout for each of our two UTXOs: ``` -$ utxo_txid_1="c1abb6951e6a9aae7e384412b69b69e59c10daac9397d01d0c52b7bc6278d589" -$ utxo_vout_1="1" -$ utxo_txid_2="ab7ca727055b812df882298f4e6e10ec699fb6250d843c813623171781f896d8" -$ utxo_vout_2="0" - -$ echo $utxo_txid_1 -c1abb6951e6a9aae7e384412b69b69e59c10daac9397d01d0c52b7bc6278d589 -$ echo $utxo_vout_1 -1 -$ echo $utxo_txid_2 -ab7ca727055b812df882298f4e6e10ec699fb6250d843c813623171781f896d8 -$ echo $utxo_vout_2 -0 +$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') ``` ### Write the Transaction @@ -78,27 +82,26 @@ Writing the new raw transaction is surprisingly simple. All you need to do is in Here's the example. Take a look at it carefully to understand where the inputs end the outputs begin: ``` -rawtxhex2=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' '''{ "'$recipient'": 0.1, "'$changeaddress'": 0.0555 }''') +$ rawtxhex2=$(bitcoin-cli -named createrawtransaction transactions='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 4.0, "'$changeaddress'": 1.8495 }''') ``` -We were _very_ careful figuring out our money math. These two UTXOs contain .156 BTC. After sending .1 BTC, we'll have .056 BTC left. We again chose .0005 BTC for the transaction fee: this transaction about twice as big, but it's still under the average transaction size quoted by Bitcoin Fees, so that should be more than enough to make this transaction go through quickly. To accomodate that fee, we set our change to .0555 BTC. If we'd messed up our math and instead set our change to .051 BTC, that additional .0045 BTC would be lost. That's $5 or $6 gone to the miners when it didn't need to be. If we'd forgot to make change at all, then the whole .056 ($70!) 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 4.0 BTC, we'll have 1.85 BTC left. We again chose .0005 BTC for the transaction fee. To accomodate that fee, we set our change to 1.849 BTC. If we'd messed up our math and instead set our change to 1.749 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_. -Back to the raw transaction itself: we'll be honest, it took us a few times to get all the commas, quotes, and brackets in the right places, writing from the command line. We got JSON errors when we didn't format things quite right; when we fixed the errors, our variable (correctly) got filled with the hex for the raw transaction. So, as always, be careful here too, and check your work: +Fortunately, we can triple-check with our JQ alias: +``` +$ btctxfee $rawtxhex2 +.0005 ``` - ### Finish It Up You can now sign, seal, and deliver your transaction, and it's yours (and the faucet's): ``` -$ bitcoin-cli signrawtransaction $rawtxhex2 -{ - "hex": "010000000289d57862bcb7520c1dd09793acda109ce5699bb61244387eae9a6a1e95b6abc1010000006a4730440220194cf452c76630419b90ef16bc9c0f31bd3187b97357eff6b610a3054968579b02200bcdb125ac182bda338c1a64d7887efd3e4eaf1a8e7f517eb7630d4dc258bf88012102f9006968b057f5212752964546d4c259f359601d00de32ec027fd84760bb4a46ffffffffd896f88117172336813c840d25b69f69ec106e4e8f2982f82d815b0527a77cab000000006a47304402201e65fe69dd231f73a9f493ca6c49503d51a766cf27be1281c9a4eefd04b4ac1c022003750d1ec93ef7be552aa55656c1860c986ef04a8733587f4f7be38707cccaf2012102f9006968b057f5212752964546d4c259f359601d00de32ec027fd84760bb4a46ffffffff0280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88acb0af5400000000001976a914b9f2579814712f82a3dadfd73e0356339c6705b488ac00000000", - "complete": true -} -$ signedtx2="010000000289d57862bcb7520c1dd09793acda109ce5699bb61244387eae9a6a1e95b6abc1010000006a4730440220194cf452c76630419b90ef16bc9c0f31bd3187b97357eff6b610a3054968579b02200bcdb125ac182bda338c1a64d7887efd3e4eaf1a8e7f517eb7630d4dc258bf88012102f9006968b057f5212752964546d4c259f359601d00de32ec027fd84760bb4a46ffffffffd896f88117172336813c840d25b69f69ec106e4e8f2982f82d815b0527a77cab000000006a47304402201e65fe69dd231f73a9f493ca6c49503d51a766cf27be1281c9a4eefd04b4ac1c022003750d1ec93ef7be552aa55656c1860c986ef04a8733587f4f7be38707cccaf2012102f9006968b057f5212752964546d4c259f359601d00de32ec027fd84760bb4a46ffffffff0280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88acb0af5400000000001976a914b9f2579814712f82a3dadfd73e0356339c6705b488ac00000000" -$ bitcoin-cli sendrawtransaction $signedtx2 -18f1a791e3f7735dbe1c92b86645ba9b1f62b8044f61efd76d082a084982c9ae +$ signedtx2=$(bitcoin-cli -named signrawtransaction hexstring=$rawtxhex2 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 +e9f5979c6a57ac9154c9583a1eec7841841dbf085212ac7ec31aff020a212c25 ``` + +[[REVISED UP TO HERE; JUST NEED TO PUT IN NEW DATA]] ### Wait As usual, your money will be in flux for a while. You used all of your UTXOs, so your `getbalance` may show that you have cash, but the transaction must be confirmed before you see a UTXO with your change. @@ -180,3 +183,4 @@ $ bitcoin-cli decoderawtransaction $rawtxhex2 ] } ``` +[[THEN NEW CONCLUSION]]