Goal
Create and sign a Bitcoin transaction with one input and two outputs. Broadcast it and wait for it to be mined. Its acceptance into the Bitcoin blockchain will prove its validity.
Contents
- Goal
- Contents
- Brief Summary
- Summary
- Downloadable Assets
- Bitcoin Transaction Toolset Hash Type Problem
- Notes
- Financial Information For This Project
- Completion Of Further Work Outlined In Previous Projects
- Project Log
Brief Summary
I have created and signed a standard Bitcoin transaction with one input and two outputs. I uploaded it to an online service for broadcast. A little while later, it was added to the Bitcoin blockchain ("mined"). Its acceptance into the Bitcoin blockchain proves its validity.
Summary
I have created and signed a standard Bitcoin transaction with one input and two outputs. I uploaded it to an online service for broadcast. A little while later, it was added to the Bitcoin blockchain ("mined"). Its acceptance into the Bitcoin blockchain proves its validity.
My working definition of a standard transaction:
- It has at least one input and at least one output.
- All input and output addresses are Pay-To-Public-Key-Hash (P2PKH).
- All input scriptSigs contain uncompressed public keys.
Original plan of action:
- Create a source address.
- Look up current Bitcoin transaction fee rates. Choose a higher-end fee rate for calculations in order to have slack.
- Perform a rough calculation of the maximum fee I should expect to pay for transactions. Choose an amount x to transfer to the source address that covers a) the maximum Bitcoin transaction fee total and b) the deposit fee for LocalBitcoins.
- Transfer x bitcoin to the source address.
- Create two destination addresses.
- Create a two-output transaction that transfers x/2 bitcoin to each of these destination addresses.
- Create two single-output transactions that transfer the bitcoin from each of these destination addresses back to my LocalBitcoins account. Note: This will require two LocalBitcoins deposit fees.
What I actually did during the project:
- Generated 32 bytes of entropy and created a source address.
- Looked up current Bitcoin transaction fee rates. Chose a higher-end fee rate for calculations in order to have slack (financial room to manoeuvre). This was 50 satoshi / byte.
- Performed a rough calculation of the maximum fee(s) I should expect to pay for transactions. Chose an amount x to transfer to the source address that covers a) the maximum Bitcoin transaction fee total and b) the deposit fee for LocalBitcoins (x2). Estimated costs to be covered by the amount transferred: 0.0007 bitcoin. Amount transferred to source address: 0.006 bitcoin (~= $21.44). Total actual costs were 0.00036438 bitcoin (~= $1.28). See the section Financial Information For This Project for details.
- Used LocalBitcoins to transfer bitcoin to the source address. This was tx_0. LocalBitcoins constructed a large transaction that included this transfer and various others.
- Assembled information for the 1-input 2-output transaction (tx_1). Downloaded the toolset for creating a transaction. Did substantial development work on the toolset.
- Looked up current Bitcoin transaction fee rates. Chose a lower-end fee rate in order to decrease costs. The fee rate was 3 satoshi / byte.
- Generated 32 bytes of entropy for signing tx_1. Created transaction tx_1. Used a transaction decoding service to check its format. The service reported a 1-byte size discrepancy. Investigating this discrepancy led to the uncovering of an error in the original toolset (the appending of the hash type to the final signed form of the transaction). This investigation is summarised in the Bitcoin Transaction Toolset Hash Type Problem section. This is almost certainly the cause of several transaction size discrepancies seen in previous projects.
- Uploaded tx_1 for broadcast.
- Looked up receiving address on LocalBitcoins: The "final address".
- Generated two 32-byte strings of entropy for signing tx_2 and tx_3.
- Assembled the information for making tx_2 and tx_3. These two transactions will send bitcoin to the final address. The final address is nonstandard (P2SH). Therefore, tx_2 and tx_3 will be nonstandard.
- Downloaded the toolset for creating nonstandard transactions. Did substantial development work on the toolset.
- Looked up current Bitcoin transaction fee rates. Chose a lower-end fee rate in order to decrease costs. The fee rate was 1 satoshi / byte.
- Created tx_2a, which had a final fee rate of 0.995 (satoshi / byte). I suspected that it would never be mined (as its fee was below 1 satoshi / byte). I didn't broadcast it.
- Created tx_2b, which had a final fee rate of 1.495 (satoshi / byte). Used a transaction decoding service to check its format. Uploaded tx_2b for broadcast.
- Logged in to LocalBitcoins. Confirmed reception of deposit.
- Looked up current Bitcoin transaction fee rates. Chose a lower-end fee rate in order to decrease costs. The fee rate was 1.5 satoshi / byte.
- Created tx_3, which had a final fee rate of 1.502 (satoshi / byte). Used a transaction decoding service to check its format. Uploaded tx_3 for broadcast.
- Logged in to LocalBitcoins. Confirmed reception of deposit.
- Rewrote parts of the toolsets. Tested that they still produced identical versions of tx_1, tx_2b, and tx_3.
- Tested file differences to find out which toolset files had changed and which had not.
- Renamed the changed files. Changed the import commands in the other files to use these new names. Tested that the toolsets still produced identical versions of tx_1 and tx_2b. This showed that there weren't any problems using the new filenames for importing.
- Added the changed files as assets of this article.
The Downloadable Assets section contains links to the assets of this article. It also contains links to the unchanged assets of other articles that are dependencies of the transaction creation toolsets.
Notes section:
The Notes section contains the following parts:
- Terms and acryonyms
- Services used during this project
- Equipment used during this project
- Addresses generated
- Transactions created
- Transaction creation data
- Further work
Downloadable Assets
Transaction creation toolset (standard transactions):
- bitcoin_functions_2.py
- bjorn_edstrom_ripemd160.py
- create_transaction_2.py
- ecdsa-0.10.tar.gz
- pypy_sha256.py
- transaction_2.py
Transaction creation toolset (nonstandard transactions):
- bitcoin_functions.py.
-- Note: nonstandard_bitcoin_functions.py still imports bitcoin_functions.py.
- bitcoin_functions_2.py
- bjorn_edstrom_ripemd160.py
- create_nonstandard_transaction_2.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions.py
- nonstandard_transaction_2.py
- pypy_sha256.py
- transaction_2.py
Combined list:
- bitcoin_functions_2.py
- bjorn_edstrom_ripemd160.py
- create_nonstandard_transaction_2.py
- create_transaction_2.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions.py
- nonstandard_transaction_2.py
- pypy_sha256.py
- transaction_2.py
Assets of this article:
List:
- bitcoin_functions_2.py
- create_nonstandard_transaction_2.py
- create_transaction_2.py
- nonstandard_transaction_2.py
- transaction_2.py
Asset: A library of functions for handling standard Bitcoin data types.
bitcoin_functions_2.py
Asset: A script that creates and signs a nonstandard Bitcoin transaction with one standard P2PKH input and one nonstandard P2SH output.
create_nonstandard_transaction_2.py
Asset: A script that creates and signs a standard Bitcoin transaction with one input and multiple outputs.
create_transaction_2.py
Asset: A library of classes for nonstandard Bitcoin transactions.
nonstandard_transaction_2.py
Asset: A library of classes for standard Bitcoin transactions.
transaction_2.py
Assets of other articles:
List:
- bitcoin_functions.py
- bjorn_edstrom_ripemd160.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions.py
- pypy_sha256.py
Asset: A library of functions for handling standard Bitcoin data types.
bitcoin_functions.py [paywalled]
Note: nonstandard_bitcoin_functions.py still imports this file.
Asset: An implementation of RIPEMD-160, written by Björn Edström.
bjorn_edstrom_ripemd160.py [paywalled]
Asset: A Python implementation of ECDSA cryptography, written by Peter Pearson.
ecdsa-0.10.tar.gz [paywalled]
Asset: A library of functions for handling nonstandard Bitcoin data types.
nonstandard_bitcoin_functions.py [paywalled]
Asset: A Python implementation of SHA256. Author unknown.
pypy_sha256.py [paywalled]
Bitcoin Transaction Toolset Hash Type Problem
Let's summarise the hash type problem that I found during this project in
- nonstandard_transaction.py
- transaction.py
Looking at the original versions of these files, I find that:
- The hash type (SIGHASH_ALL) is 1. As 1 byte, this is 0x01. As 4 bytes (little-endian), this is 0x01 00 00 00. The 4-byte version is appended to the transaction-in-signable-form before signing. The 1-byte version is appended to the signature_data after signing. These steps are implemented correctly in the code.
- However, I made a mistake. The hash type (4-byte version) is also appended to the final signed form of the transaction. This occurs in:
-- Transaction.get_signed_form() [transaction.py: line 289]
-- Transaction.get_description_of_signed_form() [transaction.py: line 312]
-- NonstandardTransaction.get_signed_form() [nonstandard_transaction.py: line 237]
-- NonstandardTransaction.get_description_of_signed_form() [nonstandard_transaction.py: line 269]
To fix the problem, delete these lines.
I'll quote the lines here:
- Transaction.get_signed_form() [transaction.py: line 289]
s += self.hash_type_4_byte
- Transaction.get_description_of_signed_form() [transaction.py: line 312]
s += "\n- hash_type_4_byte: %s" % self.hash_type_4_byte
- NonstandardTransaction.get_signed_form() [nonstandard_transaction.py: line 237]
s += self.hash_type_4_byte
- NonstandardTransaction.get_description_of_signed_form() [nonstandard_transaction.py: line 269]
s += "\n- hash_type_4_byte: %s" % self.hash_type_4_byte
Notes
Parts
- Terms and acryonyms
- Services used during this project
- Equipment used during this project
- Addresses generated
- Transactions created
- Transaction creation data
- Further work
Terms and acryonyms
- tx = transaction
- txid = transaction id
Services used during this project
I used
localbitcoins.com
to:
- store some bitcoin
- transfer some bitcoin to the source address
- receive bitcoin back from the two destination addresses
I used
bitcoinfees.earn.com
to choose fee rates for my transactions. It displays estimated delays (in blocks and in minutes) for ranges of fee rates (in satoshis / byte).
I used the search field at
live.blockcypher.com
to search for transactions by txid.
On the resulting transaction pages e.g. for tx_0:
live.blockcypher.com/btc/tx/f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
I was able to click Advanced Details / API Call, which produced a raw text dump of the transaction, e.g.
api.blockcypher.com/v1/btc/main/txs/f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e?limit=50&includeHex=true
Note: I had to read through the transaction raw text dump in order to find the index of a particular unspent output. A service that allowed someone to look up the index of an unspent output would be useful.
Procedure for finding the output index of a particular unspent output in the JSON-formatted raw transaction information (this is used when making a transaction that spends this output):
1) Copy the transaction data into a text editor. Delete everything apart from the output list. Find all '{'. Result is an integer e.g. 35.
2) Find the unspent output by searching for the source address. Select the text of all outputs that appear after it. Delete this text.
3) Find all '{'. Result is an integer e.g. 13.
4) The result of step (3) gives you the position of the unspent output in the output list e.g. it's the 13th output. Taking the initial index to be 0, the output's index would then be 12.
I used
live.blockcypher.com/btc/decodetx
to decode a signed transaction. If the service can successfully decode a transaction, this indicates that the transaction is formatted correctly.
I used
live.blockcypher.com/btc/pushtx
to upload a signed transaction for broadcast to the Bitcoin network. After the upload, the relevant transaction page (based on the txid) would then be loaded.
I used
http://blockchain.info/tx/[txid]?format=hex
to look up the raw hex form of a transaction.
Example:
blockchain.info/tx/db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4?format=hex
Equipment used during this project
My work computer: Aineko, a 2008 Macbook running Mac OS X 10.6.8 Snow Leopard, with Python 2.7.13 installed.
Addresses generated
Source address:
- Bitcoin private key:
7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5
- Bitcoin address:
16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
Destination address 1:
- Bitcoin private key:
d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85
- Bitcoin address:
1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
Destination address 2:
- Bitcoin private key:
1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27
- Bitcoin address:
1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
Final address (generated by LocalBitcoins):
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
Transactions created
Transaction details:
- tx_0: Transferred bitcoin from my LocalBitcoins account to the source address.
- tx_1: Transferred bitcoin from the source address to the two destination addresses. Initial form of tx_1 had a spurious addition of the 1-byte hash type at the end.
- tx_2a: Transferred bitcoin from destination address 1 to the final address. Never broadcast due to low fee rate.
- tx_2b: Transferred bitcoin from destination address 1 to the final address.
- tx_3: Transferred bitcoin from destination address 2 to the final address.
===== Transaction tx_0 =====
txid_0:
f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
===== Transaction tx_1 =====
txid_1:
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
Initial form of tx_1:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac0000000001
It had an invalid addition of the 1-byte hash type (01) at the end. The broadcast service removed this byte before broadcasting the transaction.
Mined version of tx_1:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000
Final fee: 774 (satoshi)
Size: 257 bytes
Fee rate: ~= 3.023 (satoshi / byte)
Time taken from broadcast to confirmation:
36 minutes
===== Transaction tx_2a =====
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f02206b2696db707130f8274c65066ea54109c55adda50dff623030f253fb042389a6014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01039304000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
tx_2a had a final fee rate of 0.995 (satoshi / byte). I suspected that it would never be mined (as its fee was below 1 satoshi / byte). I didn't broadcast it.
===== Transaction tx_2b =====
txid_2b:
90ebf8803e37f4efea6d53ea61c706d1f253d5ef0e5bc6adab5d2c8ea0361ee1
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Fee rate: 1.495 (satoshi / byte)
Time taken from broadcast to confirmation:
13 hours 46 minutes
===== Transaction tx_3 =====
txid_3:
908a47f8364d3b16298b9d6d792b314ca3e24a5cec5b3f7c65fc365a86c57758
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Fee rate: 1.502 (satoshi / byte)
Time taken from broadcast to confirmation:
13 hours 32 mins
Transaction creation data
===== Transaction tx_0 =====
On LocalBitcoins, send 0.006 bitcoin to
16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
===== Transaction tx_1 =====
Fee rate: 3 satoshi / byte
The information for the single input:
- txid (of the previous transaction that transferred the unspent output to the input address):
f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
- previous_output_index (the index of this unspent output in the previous transaction):
12
- private key (of the input address):
7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5
- input amount (amount contained in the unspent output):
0.006 bitcoin (600000 satoshi).
- 32-byte random value (in this case, entropy_1):
257c2ff4ac1606d5e42fe152c2624cffac2aa58cdfe8578a69b12beefbce68b9
The information for the two outputs:
Output 1 (to destination address 1):
- Bitcoin address:
1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
Output 2 (to destination address 2):
- Bitcoin address:
1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
===== Transaction tx_2a =====
Fee rate: 1 satoshi / byte
Input data:
- txid (of the previous transaction tx_1 that transferred the unspent output to the input address):
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
- previous_output_index (the index of this unspent output in the previous transaction):
0
-- Note: Reading the output from making tx_1, or looking at the data about it above, shows that the output sent to 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig appears first in the output list.
- private key (of the input address):
d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85
-- Note: This is the private key for destination address 1 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- input amount (amount contained in the unspent output):
0.003 bitcoin (300000 satoshi)
- 32-byte random value (in this case, entropy_2):
11964601ab4e0f24d09509ad2b72a11cedb079cbc723cea092a3dc9ca36429d7
Output data:
- destination address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- amount: 0.003 bitcoin (300000 satoshi)
===== Transaction tx_2b =====
Same as tx_2a, but with a fee rate of 1.5 satoshi / byte.
===== Transaction tx_3 =====
Fee rate: 1.5 satoshi / byte
Input data:
- txid (of the previous transaction tx_1 that transferred the unspent output to the input address):
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
- previous_output_index (the index of this unspent output in the previous transaction):
1
-- Note: Reading the output from making tx_1, or looking at the data about it above, shows that the output sent to 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P appears second in the output list.
- private key (of the input address):
1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27
-- Note: This is the private key for destination address 2 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- input amount (amount contained in the unspent output):
0.00299226 bitcoin (299226 satoshi)
- 32-byte random value (in this case, entropy_3):
7b088a64007d9d3b06d74ed15d92d6abe7b2796d5e3c4b8c3eebc51aab4576b5
Output data:
- destination address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- amount: 0.00299226 bitcoin (299226 satoshi)
Further work
What happens if the final transaction has an output with a value of 0 bitcoin? is it invalid? (or rather: will it be mined?)
Financial Information For This Project
I planned to make 3 transactions. One (the first) would have 2 outputs, to 2 different destination addresses. The second and third would be single-input single-output transactions, which would transfer the bitcoin from each destination address to my LocalBitcoins receiving address (the "final address").
I looked up current Bitcoin transaction fee rates. I chose a higher-end fee rate for calculations in order to have slack (financial room to manoeuvre). This was 50 satoshi / byte.
Standard transaction size ~= 225 bytes. Double this for the two-output transaction (so 450 bytes). Multiply high-end fee rate (50 satoshi / byte) by (450 + 225 + 225 =) 900 bytes.
50 * 900 = 45000 satoshi
= 0.0004 bitcoin
Note: A two-output transaction is not twice the size of a single-output transaction. A standard output is 34 bytes. A standard input is approximately 179 bytes, of which the signature is approximately 138 bytes. For estimating the size of a planned transaction, the numbers of inputs matters more than the number of outputs.
Other fees:
- LocalBitcoins transaction fee (for sending bitcoin) was 0.00005 BTC. This comes from the available wallet balance and is not involved in the transactions that I created later myself.
- LocalBitcoins deposit fee (for receiving bitcoin) was 0.00015 BTC.
I would have to pay the LocalBitcoins deposit fee twice, once for each of the single-input single-output transactions. This deposit fee would be subtracted from the output amount in each transaction.
costs = (expected maximum total fees) + (LocalBitcoins deposit fee x2)
= 0.0004 + 2*0.00015
= 0.0007
Bitcoin price (returned by Google) is currently ~= $3500.
Hm. $20 * (1 btc / $3500) = 20 / 3500 ~= 0.0057
x - costs = 0.0057 - 0.0007 = 0.005 btc
I decided to transfer 0.006 bitcoin to the source address. This would cover the potential costs involved in the next 3 transactions during this project.
On LocalBitcoins, I transferred 0.006 btc to:
16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
LocalBitcoin said that this was equal to $21.44.
Costs:
- tx_0: LocalBitcoins transaction fee = 0.00005 bitcoin
- tx_1: Bitcoin transaction fee = 774 satoshi = 0.00000774 bitcoin
- tx_2: Bitcoin transaction fee + LocalBitcoins deposit fee = 332 satoshi + 0.00015 bitcoin = 0.00000332 bitcoin + 0.00015 bitcoin = (0.00000332 + 0.00015) bitcoin = 0.00015332 bitcoin
- tx_3: Bitcoin transaction fee + LocalBitcoins deposit fee = 332 satoshi + 0.00015 bitcoin = 0.00000332 bitcoin + 0.00015 bitcoin = (0.00000332 + 0.00015) bitcoin = 0.00015332 bitcoin
Total costs:
0.00005 bitcoin + 0.00000774 bitcoin + 0.00015332 bitcoin + 0.00015332 bitcoin = (0.00005 + 0.00000774 + 0.00015332 + 0.00015332) = 0.00036438 bitcoin
At an exchange rate of (1 btc / $3500), this is:
0.00036438 bitcoin * ($3500 / 1 bitcoin) = 0.00036438 * 3500 = 1.27533 ~= $1.28
Double-check: Amount received back into LocalBitcoins account:
- tx_2: 0.00284668 bitcoin
- tx_3: 0.00283894 bitcoin
Final total: 0.00284668 bitcoin + 0.00283894 bitcoin = (0.00284668 + 0.00283894) bitcoin = 0.00568562 bitcoin
Original total: 0.006 bitcoin
Total costs: (original total) - (final total) = 0.006 bitcoin - 0.00568562 bitcoin = (0.006 - 0.00568562) bitcoin = 0.00031438 bitcoin
Add the LocalBitcoins transaction fee (for tx_0) to the total costs:
0.00005 bitcoin + 0.00031438 bitcoin = (0.00005 + 0.00031438) bitcoin = 0.00036438 bitcoin
This result is equal to the earlier result for [Total costs].
Completion Of Further Work Outlined In Previous Projects
During this project, I looked up some Further Work sections from previous projects and planned my work so that it would accomplish some of the goals or answer some of the questions. I forgot to mention this in the project log.
I'll quote Further Work items from previous projects, along with relevant results from this project. I'll proceed through previous projects in reverse chronological order.
Excerpt from:
Storing bitcoin on an offline Raspberry Pi
I would like to be able to transfer only a portion of the bitcoin (rather than an whole unspent output) in an offline address to another address. In order to do this, I need to be able to create transactions with two outputs - I could then set a default change output (whose destination would be the original offline address), and send only a portion of the bitcoin to the other output. This requires expansion of the existing code and careful testing.
This is possible now, using the improved toolset developed in this project, but really requires one further test: A mixed-output nonstandard transaction, with 1 P2PKH output and 1 P2SH output.
Excerpt from:
Storing bitcoin on an offline Raspberry Pi
During this project, transaction sizes (in bytes) differed slightly depending on the source.
- I estimated that a nonstandard transaction with one P2PKH input and one P2SH output should be approximately 221 bytes. All transactions that I created in this project were of this type (tx1, tx1b, tx1c, tx3).
- According to my tests after creating the transactions, they were:
-- tx1 / tx1a: 225 bytes
-- tx1b: 226 bytes
-- tx1c: 226 bytes
-- tx3: 226 bytes
- Transaction sizes according to the service live.blockcypher.com:
-- tx1 / tx1a: 221 bytes
-- tx1b: 222 bytes
-- tx1c: 222 bytes
-- tx3: 222 bytes
Investigate why these discrepancies exist, giving priority to how the estimated size is calculated. I derived the current estimate by adding up the sizes of the transaction component parts while developing the code for creating transactions.
Each discrepancy is 4 bytes. During this project, I discovered and resolved an erroneous 4-byte addition (of the 4-byte hash type, at the end of the transaction) in transaction.py and nonstandard_transaction.py. My estimation procedure did not include this 4-byte addition. The online service live.blockcypher.com ignored the last 4 bytes. The details can be found in the Bitcoin Transaction Toolset Hash Type Problem section.
Excerpt from:
Creating and signing a standard raw Bitcoin transaction: Iteration #2
The P2SH outputScript is 3 single-byte opcodes + a 20-byte redeemScriptHash i.e. 23 bytes. Will a nonstandard transaction with a single P2PKH input and a single P2SH output always be 221 bytes long?
In contrast, the P2PKH scriptPubKey is 5 single-byte opcodes + a 20-byte publicKeyHash i.e. 25 bytes. Will a standard transaction with a single P2PKH input and a single P2PKH output always be 223 bytes long?
The answer to both of these questions is "no".
Regarding question (1): In this project, transactions tx_2a and tx_2b were both nonstandard transactions with a single P2PKH input and a single P2SH output. They were each 222 bytes. The scriptSig of the standard input was 139 bytes long. Transaction tx_3, which was also a nonstandard transaction with a single P2PKH input and a single P2SH output), was 221 bytes. The scriptSig of the standard input was 138 bytes long.
Regarding question (2): In this project, transactions tx_1, tx_2a, tx_2b, and tx_3 were all signed by a single standard input. For tx_1 and tx_3, the scriptSig was 138 bytes. For tx_2a and tx_2b, the scriptSig was 139 bytes.
So, my current estimate for the size of a standard scriptSig is 138-139 bytes.
Therefore:
- My current estimate for the size of a standard 1-input 1-output transaction is 223-224 bytes.
- My current estimate for the size of a nonstandard 1-P2PKH-input 1-P2SH-output transaction is 221-222 bytes.
Excerpt from:
Creating and signing a standard raw Bitcoin transaction: Iteration #2
Add an "Actual transaction size" output (in bytes) to
create_transaction.py
and
create_nonstandard_transaction.py,
to be displayed after the transaction has been signed and its signature has been embedded into it.
- Also a corresponding "Actual fee rate" output (in satoshi / byte).
I have added these features to:
- create_transaction_2.py: Lines 389-394
- create_nonstandard_transaction_2.py: Lines 412-417
Example output:
- Size of signed transaction: 222 bytes
- (signed_tx_size - estimated_tx_size): 1 bytes
- Fee rate in signed transaction: 0.995 (satoshi / byte)
- (signed_tx_size - estimated_tx_size): 1 bytes
- Fee rate in signed transaction: 0.995 (satoshi / byte)
Excerpt from:
Creating and signing a standard raw Bitcoin transaction: Iteration #2
Construct and broadcast a standard transaction with one input and two outputs.
This was the main goal of this project and has been accomplished.
Excerpt from:
Creating and signing a standard raw Bitcoin transaction: Iteration #2
In create_transaction.py, validate the length domain of the random_value in the preparation phase, long before transaction signing is performed.
- Also do this for
create_nonstandard_transaction.py.
This has been done.
- create_transaction_2.py: Lines 118-124
- create_nonstandard_transaction_2.py: Lines 113-119
Excerpt from:
Creating and signing a standard raw Bitcoin transaction: Iteration #2
In bitcoin_functions.py, write a function called
validate_string_is_digits().
This can then be used to validate the fee control value (if fee is used rather than fee_rate) in
create_transaction.py.
- Also add this validation check in
create_nonstandard_transaction.py.
This has been done.
- create_transaction_2.py: Line 109
- create_nonstandard_transaction_2.py: Lines 104
Excerpt from:
Creating and signing a standard raw Bitcoin transaction: Iteration #2
In create_transaction.py, add a validate_txid() check. On second thought, this should actually just be a validate_hex_length() check. txids are 32-byte little-endian hashes and should be able to have any value.
- also do this for
create_nonstandard_transaction.py.
This has been done.
- create_transaction_2.py: Line 162
- create_nonstandard_transaction_2.py: Lines 160
Project Log
Plan of action:
- Create a source address.
- Look up current Bitcoin transaction fee rates. Choose a higher-end fee rate for calculations in order to have slack.
- Perform a rough calculation of the maximum fee I should expect to pay for transactions. Choose an amount x to transfer to the source address that covers a) the maximum Bitcoin transaction fee total and b) the deposit fee for LocalBitcoins.
- Transfer x bitcoin to the source address.
- Create two destination addresses.
- Create a two-output transaction that transfers x/2 bitcoin to each of these destination addresses.
- Create two single-output transactions that transfer the bitcoin from each of these destination addresses back to my LocalBitcoins account. Note: This will require two LocalBitcoins deposit fees.
Create a source address.
Use the following recipe to generate a new Bitcoin private key:
Recipe for generating entropy bytes using dice
Bitcoin private key:
7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5
Use the following recipe to derive the corresponding Bitcoin address from the private key:
Recipe for generating a Bitcoin address
Bitcoin address:
16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
Look up current Bitcoin transaction fee rates. Choose a higher-end fee rate for calculations in order to have slack.
Browse to
bitcoinfees.earn.com
Looking at the data, a reasonable choice of maximum fee rate would be 50 satoshi / byte.
Perform a rough calculation of the maximum fee I should expect to pay for transactions. Choose an amount x to transfer to the source address that covers a) the expected maximum Bitcoin transaction fee total and b) the deposit fee for LocalBitcoins.
There will be 3 transactions, of which 1 will have two outputs. Standard transaction size ~= 225 bytes. Double this for the two-output transaction (so 450 bytes). Multiply high-end fee rate (50 satoshi / byte) by (450 + 225 + 225 =) 900 bytes.
50 * 900 = 45000 satoshi
= 0.0004 bitcoin
[later update: A two-output transaction is not twice the size of a single-output transaction. A standard output is 34 bytes. A standard input is approximately 179 bytes, of which the signature is approximately 138 bytes. For estimating the size of a planned transaction, the numbers of inputs matters more than the number of outputs.]
Log in to LocalBitcoins.
LocalBitcoins transaction fee (for sending bitcoin) is currently 0.00005 BTC. This comes from the available wallet balance and is not involved in the transactions that I will create.
LocalBitcoins deposit fee (for receiving bitcoin) is currently 0.00015 BTC.
costs = (expected maximum total fees) + (LocalBitcoins deposit fee x2)
= 0.0004 + 2*0.00015
= 0.0007
Bitcoin price (returned by Google) is currently ~= $3500.
Hm. $20 * (1 btc / $3500) = 20 / 3500 ~= 0.0057
x - costs = 0.0057 - 0.0007 = 0.005 btc
I'll transfer 0.006 bitcoin to the source address. This should cover the potential costs involved in the next 3 transactions during this project.
On LocalBitcoins, transfer 0.006 btc to:
16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
LocalBitcoin says that this is equal to $21.44.
Set a timer for 1 hour.
Using the recipes linked earlier, create two destination addresses.
Destination address 1:
- Bitcoin private key:
d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85
- Bitcoin address:
1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
Destination address 2:
- Bitcoin private key:
1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27
- Bitcoin address:
1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
Timer has finished.
Go to LocalBitcoins / Wallet / Transactions.
The most recent transaction:
- 0.006 btc sent to 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
- txid:
f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
Log out of LocalBitcoins.
Browse to:
live.blockcypher.com
Search for the txid.
Result:
live.blockcypher.com/btc/tx/f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
- Confirmations: 4/6
I'll wait for 6 confirmations.
Set timer for 1 hour.
Timer has finished.
Reload the transaction page. 6+ confirmations.
Click Advanced Details / API Call.
Result:
api.blockcypher.com/v1/btc/main/txs/f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e?limit=50&includeHex=true
Excerpts from the raw data returned by the API call:
{
"block_hash": "00000000000000000028747f866d389caadabfa2514fe2d2dc4851039e30a866",
"block_height": 563140,
"block_index": 156,
[...]
"confirmed": "2019-02-15T11:36:26Z",
"received": "2019-02-15T11:35:16.802Z",
"ver": 2,
"lock_time": 563139,
"double_spend": false,
"vin_sz": 1,
"vout_sz": 35,
"confirmations": 10,
[...]
"outputs": [
{
[...]
{
"value": 600000,
"script": "76a91438a1681a09280ecb20b62cf661913e811eb3c4b188ac",
"addresses": [
"16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj"
],
"script_type": "pay-to-pubkey-hash"
},
[...]
Note: The output shown is the one that made the transfer to the source address:
16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
Let's call this "output_1".
I'll call the transaction above "tx_0".
Need to find the output index of output_1 (this is used when making a transaction that spends this output).
1) Copy the transaction data into a text editor. Delete everything apart from the output list. Find all '{'. 35 found.
2) Find output_1 by searching for the source address. Select the text of all outputs that appear after it. Delete this text.
3) Find all '{'. 13 found.
4) output_1 is the 13th output in the list. Taking the initial index to be 0, output_1's output index is 12.
Next: Create a two-output transaction that transfers x/2 bitcoin to each of these destination addresses.
This is the part that requires development work.
Create a work directory.
Browse to:
Recipe for creating and signing a standard Bitcoin transaction
Download all assets and move them to the work directory.
List of assets:
- bitcoin_functions.py
- bjorn_edstrom_ripemd160.py
- create_transaction.py
- ecdsa-0.10.tar.gz
- pypy_sha256.py
- transaction.py
Unpack the ecdsa-0.10.tar.gz asset, using the following command:
tar -zxvf ecdsa-0.10.tar.gz
This unpacking should produce a new directory named "ecdsa-0.10" in the work directory. The directory "ecdsa-0.10" should contain a directory named "ecdsa". Copy the "ecdsa" directory into the work directory.
This toolset currently handles a standard transaction with 1 input and 1 output.
I will need 32 bytes of entropy per input.
Use the following recipe to generate 32 bytes of entropy (note that this is exactly the same process used to generate a Bitcoin private key):
Recipe for generating entropy bytes using dice
I'll call the result "entropy_1".
entropy_1:
257c2ff4ac1606d5e42fe152c2624cffac2aa58cdfe8578a69b12beefbce68b9
Assemble the information for the single input:
- txid (of the previous transaction that transferred the unspent output to the input address):
f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
- previous_output_index (the index of this unspent output in the previous transaction):
12
- private key (of the input address):
7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5
- input amount (amount contained in the unspent output):
0.006 bitcoin (600000 satoshi).
- 32-byte random value (in this case, entropy_1):
257c2ff4ac1606d5e42fe152c2624cffac2aa58cdfe8578a69b12beefbce68b9
Assemble the information for the two outputs:
output 1 (to destination address 1):
- Bitcoin address:
1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
output 2 (to destination address 2):
- Bitcoin address:
1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
I'll set the change address to output 2. This means that I'll develop the code to have a dedicated change output as a feature, and in this case that will produce a transaction with two outputs.
output amounts:
- I'll send half the input amount (so 0.003 btc) to destination address 1. The rest will go to the change output (destination address 2). The transaction fee will be subtracted from the amount that goes into the change output.
fee rate:
- At first, I will use a low fee rate, and see if the resulting transaction is mined. I will increase the fee rate steadily until a version of the transaction is mined.
Note: I have read that the same entropy value should never be used to make ECDSA signatures of two different items, as this puts the private key at risk. Generate 32 bytes of entropy for each new version of the transaction.
[development work occurs here]
Substantial work completed on:
- create_transaction.py
- transaction.py
Look up current Bitcoin transaction fee rates. Choose a lower-end fee rate in order to decrease costs.
Browse to
bitcoinfees.earn.com
I see that a fee rate of 1-2 satoshi / byte has an estimated delay of 1-4 blocks (0-80 minutes).
I see that a fee rate of 3-4 satoshi / byte has an estimated delay of 0-2 blocks (0-50 minutes).
I'll use a fee rate of 3 satoshi / byte.
aineko:work2 stjohnpiano$ python create_transaction.py
### START CREATION OF BITCOIN TRANSACTION
- Fee type: fee_rate
- Fee rate: 3.0 (satoshi / byte)
- Number of inputs (i.e. as-yet-unspent outputs): 1
- Number of outputs: 1
-- Note: This does not include the change output.
- Change address: 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- Input addresses, with total-value-to-be-sent:
-- 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj: 0.00600000
- Output addresses, with total-value-to-be-received:
-- 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig: 0.00300000
- Total value of all inputs: 0.00600000
- Total value of all outputs: 0.00300000
- Total value of all inputs is greater than total value of all outputs.
-- Extra value: 0.00300000
-- This extra value will be sent to the change address.
- Estimated transaction size: 258 bytes
- Fee rate: 3.0 (satoshi / byte)
- Calculate 258 * 3.0 and round up to nearest satoshi.
- Final fee: 774 (satoshi)
- Final fee rate (using estimated transaction size): 3.0000 (satoshi per byte)
- Fee subtracted from amount-to-be-sent-to-change-address.
- New amount to be sent to change address: 299226 (satoshi)
- Size of signed transaction: 258 bytes
- (signed_tx_size - estimated_tx_size): 0 bytes
- Fee rate in signed transaction: 3.0 (satoshi / byte)
Input 0:
Input: {40 bytes unsigned, 66 bytes signable, 179 bytes signed}
- [data] previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
- [data] previous_output_index: 0c000000 (4 bytes)
- [signed form] script_length: 8a (1 bytes)
- [signed form] scriptSig: 47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a (138 bytes)
- [data] sequence: ffffffff (4 bytes)
- [used for signing] private_key_hex: 7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5 (32 bytes)
- [destination, goes into scriptSig] public_key_hex: 04108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a (65 bytes)
- [signable form] script_length_scriptPubKey: 19 (1 bytes)
- [signable form] scriptPubKey: 76a91438a1681a09280ecb20b62cf661913e811eb3c4b188ac (25 bytes)
- [more info] address: 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
- [more info] previous_output_index_int: 12
- [more info] txid: f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
Output 0:
Output: {34 bytes}
- [data] value: e093040000000000 (8 bytes)
- [data] script_length: 19 (1 bytes)
- [data] scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- [more info] address: 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- [more info] bitcoin_amount: 0.003
- [more info] satoshi_amount: 300000
- [more info] public_key_hash_hex: c8833727be832b6634d8ddf7bfcf51e379b28f63
Output 1:
Output: {34 bytes}
- [data] value: da90040000000000 (8 bytes)
- [data] script_length: 19 (1 bytes)
- [data] scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- [more info] address: 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- [more info] bitcoin_amount: 0.00299226
- [more info] satoshi_amount: 299226
- [more info] public_key_hash_hex: 875a093668adff783d0835f4db655c5a47a0ceaa
Transaction (unsigned form): {118 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {40 bytes}
-- previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
-- previous_output_index: 0c000000 (4 bytes)
-- script_length: [none] (0 bytes)
-- scriptSig: [none] (0 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 02 (1 bytes)
- Output 0: {34 bytes}
-- value: e093040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- Output 1: {34 bytes}
-- value: da90040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- block_lock_time: 00000000 (4 bytes)
Transaction (signable form 0): {148 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0 [to be used to sign this signable form]: {66 bytes}
-- previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
-- previous_output_index: 0c000000 (4 bytes)
-- script_length_scriptPubKey: 19 (1 bytes)
-- scriptPubKey: 76a91438a1681a09280ecb20b62cf661913e811eb3c4b188ac (25 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 02 (1 bytes)
- Output 0: {34 bytes}
-- value: e093040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- Output 1: {34 bytes}
-- value: da90040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- block_lock_time: 00000000 (4 bytes)
- hash_type_4_byte: 01000000 (4 bytes)
Transaction (signed form): {258 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {179 bytes}
-- previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
-- previous_output_index: 0c000000 (4 bytes)
-- script_length: 8a (1 bytes)
-- scriptSig: 47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a (138 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 02 (1 bytes)
- Output 0: {34 bytes}
-- value: e093040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- Output 1: {34 bytes}
-- value: da90040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- block_lock_time: 00000000 (4 bytes)
- hash_type_1_byte: 01 (1 bytes)
Signed transaction:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac0000000001
### END CREATION OF BITCOIN TRANSACTION
Signed transaction:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac0000000001
Browse to:
live.blockcypher.com/btc/decodetx
If this service can successfully decode a transaction, this indicates that the transaction is formatted correctly.
Paste the signed transaction into the text box named "Transaction Hex". Network is set to "Bitcoin".
Click "Decode Transaction".
Result:
{
"addresses": [
"16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj",
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig",
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P"
],
"block_height": -1,
"block_index": -1,
"confirmations": 0,
"double_spend": false,
"fees": 774,
"hash": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4",
"inputs": [
{
"addresses": [
"16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj"
],
"age": 563140,
"output_index": 12,
"output_value": 600000,
"prev_hash": "f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e",
"script": "47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a",
"script_type": "pay-to-pubkey-hash",
"sequence": 4294967295
}
],
"outputs": [
{
"addresses": [
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig"
],
"script": "76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac",
"script_type": "pay-to-pubkey-hash",
"value": 300000
},
{
"addresses": [
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P"
],
"script": "76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac",
"script_type": "pay-to-pubkey-hash",
"value": 299226
}
],
"preference": "low",
"received": "2019-02-17T21:18:09.32464057Z",
"relayed_by": "34.238.127.162",
"size": 257,
"total": 599226,
"ver": 1,
"vin_sz": 1,
"vout_sz": 2
}
Looks good. No immediate error reported.
Hm. It reports the tx size to be 257 bytes.
I found earlier that it was 258 bytes.
Let's test again:
aineko:work2 stjohnpiano$ tx="01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac0000000001"
aineko:work2 stjohnpiano$ echo -n $tx | wc -c
516
516/2 = 258
Hm.
Is the service chopping off the last byte (the 1-byte hash type)?
=== later update:
yes, it is... but:
a) I made a mistake in my earlier published code (transaction.py), which was appending a 4-byte hash type to the entire signed form of the transaction. The hash type is only appended to the signature hex (in its 1-byte form). It is appended to the entire transaction (in its 4-byte form) in the transaction-in-signable-form, in preparation for making a signature using a particular input's private key.
b) I recall that in previous projects I observed several 4-byte discrepancies between my measurements of some transaction lengths and the measurements made by this online transaction decoding service.
c) I should not have been appending the hash type, which explains the previous 4-byte length discrepancies.
d) In this project, I remembered that the hash type, when appended in the final form, should actually be the 1-byte version. I changed the hash type appended to the entire signed transaction to the 1-byte form. This produced the 1-byte discrepancy observed just above. I have now removed the code that appends the hash type.
It's interesting to note that:
- The service did not reject the transaction.
- The service correctly parsed the transaction, stopping when it reached the end, and discarding the remainder (the hash type, whether 1-byte or 4-byte).
So, for future reference (e.g. unit tests), the proper hex form of this transaction is:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000
I've confirmed this by looking up the hex form of the transaction (using the txid) in another blockchain information service.
Format of HTTP request:
http://blockchain.info/tx/[txid]?format=hex
So:
blockchain.info/tx/db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4?format=hex
This request returns the correct form of the signed transaction (i.e. last byte "01" removed) shown above.
===
Let's broadcast the signed transaction.
Browse to:
live.blockcypher.com/btc/pushtx
Paste the signed transaction into the text box named "Transaction Hex". Network is set to "Bitcoin".
Click "Broadcast Transaction".
Result:
Page reloads. Nothing appears to have occurred. Hm.
Try again.
Result:
Transaction page loads:
live.blockcypher.com/btc/tx/db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
Details:
- Transaction Successfully Broadcst
- AMOUNT TRANSACTED: 0.00599226 BTC
- FEES: 0.00000774 BTC
- Confirmations: 0/6
- Miner Preference: LOW
- Size: 257 bytes
- Version: 1
- Relayed By: 54.196.214.252
Approximate datetime: 2019-02-17 21:30
[next day]
Browse to transaction page again.
Confirmations: 6+
Click "Advanced Details". Click "API Call".
Result: tx_1
{
"block_hash": "000000000000000000128646dc7f7f4bb29c2dd3a7e3735eabf6385ce8463dab",
"block_height": 563500,
"block_index": 2168,
"hash": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4",
"hex": "01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000",
"addresses": [
"16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj",
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P",
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig"
],
"total": 599226,
"fees": 774,
"size": 257,
"preference": "low",
"relayed_by": "54.196.214.252",
"confirmed": "2019-02-17T22:03:04Z",
"received": "2019-02-17T21:27:37.133Z",
"ver": 1,
"double_spend": false,
"vin_sz": 1,
"vout_sz": 2,
"confirmations": 94,
"confidence": 1,
"inputs": [
{
"prev_hash": "f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e",
"output_index": 12,
"script": "47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a",
"output_value": 600000,
"sequence": 4294967295,
"addresses": [
"16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj"
],
"script_type": "pay-to-pubkey-hash",
"age": 563140
}
],
"outputs": [
{
"value": 300000,
"script": "76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac",
"addresses": [
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig"
],
"script_type": "pay-to-pubkey-hash"
},
{
"value": 299226,
"script": "76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac",
"addresses": [
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P"
],
"script_type": "pay-to-pubkey-hash"
}
]
}
Key details:
- block_hash:
000000000000000000128646dc7f7f4bb29c2dd3a7e3735eabf6385ce8463dab
- block_height: 563500
- confirmed: 2019-02-17T22:03:04Z
- received: 2019-02-17T21:27:37Z
- txid:
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
- vout_sz (number of outputs): 2
Time taken between reception and confirmation:
~= 22:03 - 21:27 ~= 36 minutes
Next: Look up my current receiving address on LocalBitcoins. I'll call this the "final address". When LocalBitcoins receives a payment to the receiving address, it will generate a new one. However, the old one will remain valid for 12 months.
Then, I'll create two separate nonstandard transactions that move the bitcoin in each destination address to the final address, minus a transaction fee. I'll do some development work on the toolset parts that handle nonstandard transactions.
Log in to LocalBitcoins. Browse to Wallet / Receive bitcoins.
Current receiving address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
Next: I will need 32 bytes of entropy per input. Two nonstandard transactions, each with one input, so I need two 32-byte entropy values.
Using Recipe for generating entropy bytes using dice, generate two 32-byte entropy values.
I'll call the results "entropy_2" and "entropy_3".
entropy_2:
11964601ab4e0f24d09509ad2b72a11cedb079cbc723cea092a3dc9ca36429d7
entropy_3:
7b088a64007d9d3b06d74ed15d92d6abe7b2796d5e3c4b8c3eebc51aab4576b5
Assemble the information for making the two nonstandard transactions.
Transaction tx_2:
Input data:
- txid (of the previous transaction tx_1 that transferred the unspent output to the input address):
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
- previous_output_index (the index of this unspent output in the previous transaction):
0
-- Note: Reading the output from making tx_1, or looking at the data about it above, shows that the output sent to 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig appears first in the output list.
- private key (of the input address):
d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85
-- Note: This is the private key for destination address 1 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- input amount (amount contained in the unspent output):
0.003 bitcoin (300000 satoshi)
- 32-byte random value (in this case, entropy_2):
11964601ab4e0f24d09509ad2b72a11cedb079cbc723cea092a3dc9ca36429d7
Output data:
- destination address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- amount: 0.003 bitcoin (300000 satoshi)
Transaction tx_3:
Input data:
- txid (of the previous transaction tx_1 that transferred the unspent output to the input address):
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
- previous_output_index (the index of this unspent output in the previous transaction):
1
-- Note: Reading the output from making tx_1, or looking at the data about it above, shows that the output sent to 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P appears second in the output list.
- private key (of the input address):
1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27
-- Note: This is the private key for destination address 2 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- input amount (amount contained in the unspent output):
0.00299226 bitcoin (299226 satoshi)
- 32-byte random value (in this case, entropy_3):
7b088a64007d9d3b06d74ed15d92d6abe7b2796d5e3c4b8c3eebc51aab4576b5
Output data:
- destination address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- amount: 0.00299226 bitcoin (299226 satoshi)
Create another work directory.
Browse to:
Recipe for creating and signing a nonstandard Bitcoin transaction
Download all assets and move them to the work directory.
List of assets:
- bitcoin_functions.py
- bjorn_edstrom_ripemd160.py
- create_nonstandard_transaction.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions.py
- nonstandard_transaction.py
- pypy_sha256.py
- transaction.py
Unpack the ecdsa-0.10.tar.gz asset, using the following command:
tar -zxvf ecdsa-0.10.tar.gz
This unpacking should produce a new directory named "ecdsa-0.10" in the work directory. The directory "ecdsa-0.10" should contain a directory named "ecdsa". Copy the "ecdsa" directory into the work directory.
This toolset currently handles a standard transaction with 1 input and 1 output.
Replace transaction.py in this work directory with the modified transaction.py developed during the construction of tx_1.
Confirm that no changes have occurred in the other dependency files shared between the standard and nonstandard transaction recipes.
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work2/bitcoin_functions.py work3/bitcoin_functions.py
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work2/bjorn_edstrom_ripemd160.py work3/bjorn_edstrom_ripemd160.py
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff -r work2/ecdsa work3/ecdsa
Only in work2/ecdsa: __init__.pyc
Only in work2/ecdsa: _version.pyc
Only in work2/ecdsa: curves.pyc
Only in work2/ecdsa: der.pyc
Only in work2/ecdsa: ecdsa.pyc
Only in work2/ecdsa: ellipticcurve.pyc
Only in work2/ecdsa: keys.pyc
Only in work2/ecdsa: numbertheory.pyc
Only in work2/ecdsa: rfc6979.pyc
Only in work2/ecdsa: six.pyc
Only in work2/ecdsa: util.pyc
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work2/pypy_sha256.py work3/pypy_sha256.py
Good.
[development occurs here]
Substantial work completed on:
- create_nonstandard_transaction.py
- nonstandard_transaction.py
Some work completed on:
- bitcoin_functions.py
- transaction.py
Look up current Bitcoin transaction fee rates. Choose a lower-end fee rate in order to decrease costs.
Browse to
bitcoinfees.earn.com
I see that a fee rate of 1-2 satoshi / byte has an estimated delay of 2-10 blocks (5-180 minutes).
I see that a fee rate of 3-4 satoshi / byte has an estimated delay of 1-5 blocks (0-80 minutes).
I'll use a fee rate of 1 satoshi / byte.
I'll create transaction tx_2.
aineko:work3 stjohnpiano$ python create_nonstandard_transaction.py
### START CREATION OF NONSTANDARD BITCOIN TRANSACTION
- Fee type: fee_rate
- Fee rate: 1.0 (satoshi / byte)
- Number of inputs (i.e. as-yet-unspent outputs): 1
- Number of outputs: 1
- Change address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- Amount to be sent to the change address: 0.00300000
- Input addresses, with total-value-to-be-sent:
-- 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig: 0.00300000
- Output addresses, with total-value-to-be-received:
-- 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU: 0.00300000
- Total value of all inputs: 0.00300000
- Total value of all outputs: 0.00300000
- Total value of all inputs exactly matches total value of all outputs.
- Estimated transaction size: 221 bytes
- Fee rate: 1.0 (satoshi / byte)
- Calculate 221 * 1.0 and round up to nearest satoshi.
- Final fee: 221 (satoshi)
- Final fee rate (using estimated transaction size): 1.0000 (satoshi per byte)
- Fee subtracted from amount to be sent to change address.
- New amount to be sent to change address: 299779 (satoshi)
- Size of signed transaction: 222 bytes
- (signed_tx_size - estimated_tx_size): 1 bytes
- Fee rate in signed transaction: 0.995 (satoshi / byte)
Input 0:
Input: {40 bytes unsigned, 66 bytes signable, 180 bytes signed}
- [data] previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
- [data] previous_output_index: 00000000 (4 bytes)
- [signed form] script_length: 8b (1 bytes)
- [signed form] scriptSig: 483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f02206b2696db707130f8274c65066ea54109c55adda50dff623030f253fb042389a6014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363 (139 bytes)
- [data] sequence: ffffffff (4 bytes)
- [used for signing] private_key_hex: d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85 (32 bytes)
- [destination, goes into scriptSig] public_key_hex: 04876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363 (65 bytes)
- [signable form] script_length_scriptPubKey: 19 (1 bytes)
- [signable form] scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- [more info] address: 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- [more info] previous_output_index_int: 0
- [more info] txid: db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
Output 0 (P2SH):
P2SH Output: {32 bytes}
- [data] value: 0393040000000000 (8 bytes)
- [data] script_length: 17 (1 bytes)
- [data] script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- [more info] address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- [more info] bitcoin_amount: 0.00299779
- [more info] satoshi_amount: 299779
- [more info] redeem_script_hash_hex: 3a1c39fcbfd4a1407deddf47249bbfccb12a7478
Nonstandard Transaction (unsigned form): {82 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {40 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 00000000 (4 bytes)
-- script_length: [none] (0 bytes)
-- scriptSig: [none] (0 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 0393040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
Nonstandard Transaction (signable form 0): {112 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0 [to be used to sign this signable form]: {66 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 00000000 (4 bytes)
-- script_length_scriptPubKey: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 0393040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
- hash_type_4_byte: 01000000 (4 bytes)
Nonstandard Transaction (signed form): {222 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {180 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 00000000 (4 bytes)
-- script_length: 8b (1 bytes)
-- scriptSig: 483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f02206b2696db707130f8274c65066ea54109c55adda50dff623030f253fb042389a6014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363 (139 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 0393040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
Signed transaction:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f02206b2696db707130f8274c65066ea54109c55adda50dff623030f253fb042389a6014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01039304000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
### END CREATION OF BITCOIN TRANSACTION
tx_2:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f02206b2696db707130f8274c65066ea54109c55adda50dff623030f253fb042389a6014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01039304000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Size: 222 bytes
Note that the scriptSig was 139 bytes (not 138 bytes as expected).
I think that the signature length can vary by a byte or so.
Hm. This causes the actual fee rate to be:
- Fee rate in signed transaction: 0.995 (satoshi / byte)
I suspect that this one will never be mined (as its fee is below 1 satoshi / byte).
Set fee rate to 1.5 and re-run. I can re-use the entropy value for signing because this transaction has not been broadcast.
I'll call the transaction above tx_2a and the one below tx_2b.
aineko:work3 stjohnpiano$ python create_nonstandard_transaction.py
### START CREATION OF NONSTANDARD BITCOIN TRANSACTION
- Fee type: fee_rate
- Fee rate: 1.5 (satoshi / byte)
- Number of inputs (i.e. as-yet-unspent outputs): 1
- Number of outputs: 1
- Change address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- Amount to be sent to the change address: 0.00300000
- Input addresses, with total-value-to-be-sent:
-- 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig: 0.00300000
- Output addresses, with total-value-to-be-received:
-- 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU: 0.00300000
- Total value of all inputs: 0.00300000
- Total value of all outputs: 0.00300000
- Total value of all inputs exactly matches total value of all outputs.
- Estimated transaction size: 221 bytes
- Fee rate: 1.5 (satoshi / byte)
- Calculate 221 * 1.5 and round up to nearest satoshi.
- Final fee: 332 (satoshi)
- Final fee rate (using estimated transaction size): 1.5023 (satoshi per byte)
- Fee subtracted from amount to be sent to change address.
- New amount to be sent to change address: 299668 (satoshi)
- Size of signed transaction: 222 bytes
- (signed_tx_size - estimated_tx_size): 1 bytes
- Fee rate in signed transaction: 1.495 (satoshi / byte)
Input 0:
Input: {40 bytes unsigned, 66 bytes signable, 180 bytes signed}
- [data] previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
- [data] previous_output_index: 00000000 (4 bytes)
- [signed form] script_length: 8b (1 bytes)
- [signed form] scriptSig: 483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363 (139 bytes)
- [data] sequence: ffffffff (4 bytes)
- [used for signing] private_key_hex: d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85 (32 bytes)
- [destination, goes into scriptSig] public_key_hex: 04876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363 (65 bytes)
- [signable form] script_length_scriptPubKey: 19 (1 bytes)
- [signable form] scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- [more info] address: 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- [more info] previous_output_index_int: 0
- [more info] txid: db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
Output 0 (P2SH):
P2SH Output: {32 bytes}
- [data] value: 9492040000000000 (8 bytes)
- [data] script_length: 17 (1 bytes)
- [data] script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- [more info] address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- [more info] bitcoin_amount: 0.00299668
- [more info] satoshi_amount: 299668
- [more info] redeem_script_hash_hex: 3a1c39fcbfd4a1407deddf47249bbfccb12a7478
Nonstandard Transaction (unsigned form): {82 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {40 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 00000000 (4 bytes)
-- script_length: [none] (0 bytes)
-- scriptSig: [none] (0 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 9492040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
Nonstandard Transaction (signable form 0): {112 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0 [to be used to sign this signable form]: {66 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 00000000 (4 bytes)
-- script_length_scriptPubKey: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 9492040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
- hash_type_4_byte: 01000000 (4 bytes)
Nonstandard Transaction (signed form): {222 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {180 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 00000000 (4 bytes)
-- script_length: 8b (1 bytes)
-- scriptSig: 483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363 (139 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 9492040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
Signed transaction:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
### END CREATION OF BITCOIN TRANSACTION
tx_2b:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
- Size of signed transaction: 222 bytes
- Fee rate in signed transaction: 1.495 (satoshi / byte)
The scriptSig was 139 bytes (not 138 bytes as expected).
Browse to:
live.blockcypher.com/btc/decodetx
If this service can successfully decode a transaction, this indicates that the transaction is formatted correctly.
Paste the signed transaction into the text box named "Transaction Hex". Network is set to "Bitcoin".
Click "Decode Transaction".
Result:
{
"addresses": [
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig",
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"block_height": -1,
"block_index": -1,
"confirmations": 0,
"double_spend": false,
"fees": 332,
"hash": "90ebf8803e37f4efea6d53ea61c706d1f253d5ef0e5bc6adab5d2c8ea0361ee1",
"inputs": [
{
"addresses": [
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig"
],
"age": 563500,
"output_index": 0,
"output_value": 300000,
"prev_hash": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4",
"script": "483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363",
"script_type": "pay-to-pubkey-hash",
"sequence": 4294967295
}
],
"outputs": [
{
"addresses": [
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"script": "a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887",
"script_type": "pay-to-script-hash",
"value": 299668
}
],
"preference": "low",
"received": "2019-02-19T10:31:16.480780441Z",
"relayed_by": "54.80.115.59",
"size": 222,
"total": 299668,
"ver": 1,
"vin_sz": 1,
"vout_sz": 1
}
Looks good. No immediate error reported.
The service reports the transaction size to be 222 bytes, identical to my earlier measurement.
Let's broadcast the signed transaction.
Browse to:
live.blockcypher.com/btc/pushtx
Paste the signed transaction into the text box named "Transaction Hex". Network is set to "Bitcoin".
Click "Broadcast Transaction".
Result:
Transaction page loads:
live.blockcypher.com/btc/tx/90ebf8803e37f4efea6d53ea61c706d1f253d5ef0e5bc6adab5d2c8ea0361ee1
Details:
- Transaction Successfully Broadcst
- AMOUNT TRANSACTED: 0.00299668 BTC
- FEES: 0.00000332 BTC
- Confirmations: 0/6
- Miner Preference: LOW
- Size: 222 bytes
- Version: 1
- Relayed By: 3.81.224.246
Approximate datetime: 2019-02-19 10:40
[I've reloaded the transaction page a few times]
Datetime: 2019-02-20 12:12
Refresh transaction page.
Confirmations: 6+
Click "Advanced Details". Click "API Call".
Result: tx_2
{
"block_hash": "0000000000000000001da0d803032922d8e31dbb286e9f7e056e2e3e8ccdea86",
"block_height": 563825,
"block_index": 1336,
"hash": "90ebf8803e37f4efea6d53ea61c706d1f253d5ef0e5bc6adab5d2c8ea0361ee1",
"hex": "0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000",
"addresses": [
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig",
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"total": 299668,
"fees": 332,
"size": 222,
"preference": "low",
"relayed_by": "3.81.224.246",
"confirmed": "2019-02-20T00:18:15Z",
"received": "2019-02-19T10:32:45.295Z",
"ver": 1,
"double_spend": false,
"vin_sz": 1,
"vout_sz": 1,
"confirmations": 59,
"confidence": 1,
"inputs": [
{
"prev_hash": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4",
"output_index": 0,
"script": "483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363",
"output_value": 300000,
"sequence": 4294967295,
"addresses": [
"1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig"
],
"script_type": "pay-to-pubkey-hash",
"age": 563500
}
],
"outputs": [
{
"value": 299668,
"script": "a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887",
"spent_by": "c23050d424c2e826b51994c6111a7caae335f026292e55f59518f7e1c4e50bc6",
"addresses": [
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"script_type": "pay-to-script-hash"
}
]
}
Key details:
- block_hash:
0000000000000000001da0d803032922d8e31dbb286e9f7e056e2e3e8ccdea86
- block_height: 563825
- confirmed: 2019-02-20T00:18:15Z
- received: 2019-02-19T10:32:45.295Z
- txid ("hash"):
90ebf8803e37f4efea6d53ea61c706d1f253d5ef0e5bc6adab5d2c8ea0361ee1
- vout_sz (number of outputs): 1
Time taken between reception and confirmation:
~= (2019-02-20 - 2019-02-19) + (00:18 - 10:32)
= (24 hours) + (-10:14)
= 24:00 - 10:14
= 13:46
= 13 hours 46 minutes from broadcast to confirmation.
Log in to LocalBitcoins.
Browse to Wallet / Transactions.
Most recent transaction:
- Date = 02/20/2019 01:32
- Received BTC = 0.00284668
- Sent BTC =
- Description = Deposit to 36zGvt......
- Deposit Fee BTC = 0.00015000
Good. Deposit confirmed.
Next: Transaction tx_3.
Information assembled earlier:
Transaction tx_3:
Input data:
- txid (of the previous transaction tx_1 that transferred the unspent output to the input address):
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
- previous_output_index (the index of this unspent output in the previous transaction):
1
-- Note: Reading the output from making tx_1, or looking at the data about it above, shows that the output sent to 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P appears second in the output list.
- private key (of the input address):
1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27
-- Note: This is the private key for destination address 2 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- input amount (amount contained in the unspent output):
0.00299226 bitcoin (299226 satoshi)
- 32-byte random value (in this case, entropy_3):
7b088a64007d9d3b06d74ed15d92d6abe7b2796d5e3c4b8c3eebc51aab4576b5
Output data:
- destination address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- amount: 0.00299226 bitcoin (299226 satoshi)
Look up current Bitcoin transaction fee rates. Choose a lower-end fee rate in order to decrease costs.
Browse to
bitcoinfees.earn.com
I see that a fee rate of 1-2 satoshi / byte has an estimated delay of 3-19 blocks (15-300 minutes).
I see that a fee rate of 3-4 satoshi / byte has an estimated delay of 2-13 blocks (10-240 minutes).
I'll use a fee rate of 1.5 satoshi / byte.
I'll create transaction tx_3.
aineko:work3 stjohnpiano$ python create_nonstandard_transaction.py
### START CREATION OF NONSTANDARD BITCOIN TRANSACTION
- Fee type: fee_rate
- Fee rate: 1.5 (satoshi / byte)
- Number of inputs (i.e. as-yet-unspent outputs): 1
- Number of outputs: 1
- Change address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- Amount to be sent to the change address: 0.00299226
- Input addresses, with total-value-to-be-sent:
-- 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P: 0.00299226
- Output addresses, with total-value-to-be-received:
-- 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU: 0.00299226
- Total value of all inputs: 0.00299226
- Total value of all outputs: 0.00299226
- Total value of all inputs exactly matches total value of all outputs.
- Estimated transaction size: 221 bytes
- Fee rate: 1.5 (satoshi / byte)
- Calculate 221 * 1.5 and round up to nearest satoshi.
- Final fee: 332 (satoshi)
- Final fee rate (using estimated transaction size): 1.5023 (satoshi per byte)
- Fee subtracted from amount to be sent to change address.
- New amount to be sent to change address: 298894 (satoshi)
- Size of signed transaction: 221 bytes
- (signed_tx_size - estimated_tx_size): 0 bytes
- Fee rate in signed transaction: 1.502 (satoshi / byte)
Input 0:
Input: {40 bytes unsigned, 66 bytes signable, 179 bytes signed}
- [data] previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
- [data] previous_output_index: 01000000 (4 bytes)
- [signed form] script_length: 8a (1 bytes)
- [signed form] scriptSig: 47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7 (138 bytes)
- [data] sequence: ffffffff (4 bytes)
- [used for signing] private_key_hex: 1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27 (32 bytes)
- [destination, goes into scriptSig] public_key_hex: 040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7 (65 bytes)
- [signable form] script_length_scriptPubKey: 19 (1 bytes)
- [signable form] scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- [more info] address: 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- [more info] previous_output_index_int: 1
- [more info] txid: db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
Output 0 (P2SH):
P2SH Output: {32 bytes}
- [data] value: 8e8f040000000000 (8 bytes)
- [data] script_length: 17 (1 bytes)
- [data] script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- [more info] address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- [more info] bitcoin_amount: 0.00298894
- [more info] satoshi_amount: 298894
- [more info] redeem_script_hash_hex: 3a1c39fcbfd4a1407deddf47249bbfccb12a7478
Nonstandard Transaction (unsigned form): {82 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {40 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 01000000 (4 bytes)
-- script_length: [none] (0 bytes)
-- scriptSig: [none] (0 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 8e8f040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
Nonstandard Transaction (signable form 0): {112 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0 [to be used to sign this signable form]: {66 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 01000000 (4 bytes)
-- script_length_scriptPubKey: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 8e8f040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
- hash_type_4_byte: 01000000 (4 bytes)
Nonstandard Transaction (signed form): {221 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {179 bytes}
-- previous_output_hash: f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb (32 bytes)
-- previous_output_index: 01000000 (4 bytes)
-- script_length: 8a (1 bytes)
-- scriptSig: 47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7 (138 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 01 (1 bytes)
- Output 0 (P2SH): {32 bytes}
-- value: 8e8f040000000000 (8 bytes)
-- script_length: 17 (1 bytes)
-- script: a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887 (23 bytes)
- block_lock_time: 00000000 (4 bytes)
Signed transaction:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
### END CREATION OF BITCOIN TRANSACTION
tx_3:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
- Size of signed transaction: 221 bytes
- (signed_tx_size - estimated_tx_size): 0 bytes
- Fee rate in signed transaction: 1.502 (satoshi / byte)
The scriptSig was 138 bytes as expected.
Browse to:
live.blockcypher.com/btc/decodetx
If this service can successfully decode a transaction, this indicates that the transaction is formatted correctly.
Paste the signed transaction into the text box named "Transaction Hex". Network is set to "Bitcoin".
Click "Decode Transaction".
Result:
{
"addresses": [
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P",
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"block_height": -1,
"block_index": -1,
"confirmations": 0,
"double_spend": false,
"fees": 332,
"hash": "908a47f8364d3b16298b9d6d792b314ca3e24a5cec5b3f7c65fc365a86c57758",
"inputs": [
{
"addresses": [
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P"
],
"age": 563500,
"output_index": 1,
"output_value": 299226,
"prev_hash": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4",
"script": "47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7",
"script_type": "pay-to-pubkey-hash",
"sequence": 4294967295
}
],
"outputs": [
{
"addresses": [
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"script": "a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887",
"script_type": "pay-to-script-hash",
"value": 298894
}
],
"preference": "low",
"received": "2019-02-20T14:19:05.184115287Z",
"relayed_by": "54.204.80.140",
"size": 221,
"total": 298894,
"ver": 1,
"vin_sz": 1,
"vout_sz": 1
}
Looks good. No immediate error reported.
The service reports that the tx size is 221 bytes, identical to my earlier measurement.
Let's broadcast the signed transaction.
Browse to:
live.blockcypher.com/btc/pushtx
Paste the signed transaction into the text box named "Transaction Hex". Network is set to "Bitcoin".
Click "Broadcast Transaction".
Result:
Transaction page loads:
live.blockcypher.com/btc/tx/908a47f8364d3b16298b9d6d792b314ca3e24a5cec5b3f7c65fc365a86c57758
Details:
- Transaction Successfully Broadcst
- AMOUNT TRANSACTED: 0.00298894 BTC
- FEES: 0.00000332 BTC
- Confirmations: 0/6
- Miner Preference: LOW
- Size: 221 bytes
- Version: 1
- Relayed By: 54.237.198.64
Approximate datetime: 2019-02-20 14:21
[I've reloaded the transaction page a few times]
Datetime: 2019-02-21 09:43
Refresh transaction page.
Confirmations: 6+
Click "Advanced Details". Click "API Call".
Result: tx_3
{
"block_hash": "00000000000000000019d61b8f963281c310cbded51fc0858503ae1254cea0c5",
"block_height": 563958,
"block_index": 2232,
"hash": "908a47f8364d3b16298b9d6d792b314ca3e24a5cec5b3f7c65fc365a86c57758",
"hex": "0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000",
"addresses": [
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P",
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"total": 298894,
"fees": 332,
"size": 221,
"preference": "low",
"relayed_by": "54.237.198.64",
"confirmed": "2019-02-21T00:47:38Z",
"received": "2019-02-20T14:19:55.049Z",
"ver": 1,
"double_spend": false,
"vin_sz": 1,
"vout_sz": 1,
"confirmations": 47,
"confidence": 1,
"inputs": [
{
"prev_hash": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4",
"output_index": 1,
"script": "47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7",
"output_value": 299226,
"sequence": 4294967295,
"addresses": [
"1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P"
],
"script_type": "pay-to-pubkey-hash",
"age": 563500
}
],
"outputs": [
{
"value": 298894,
"script": "a9143a1c39fcbfd4a1407deddf47249bbfccb12a747887",
"spent_by": "ee91c7c2c3fd0ea2cf07726feff9033b09479856ee397b44af299dacaaa24eed",
"addresses": [
"36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU"
],
"script_type": "pay-to-script-hash"
}
]
}
Key details:
- block_hash:
00000000000000000019d61b8f963281c310cbded51fc0858503ae1254cea0c5
- block_height: 563958
- confirmed: 2019-02-21T00:47:38Z
- received: 2019-02-20T14:19:55.049Z
- txid ("hash"):
908a47f8364d3b16298b9d6d792b314ca3e24a5cec5b3f7c65fc365a86c57758
- vout_sz (number of outputs): 1
Time taken between reception and confirmation:
~= (2019-02-21 - 2019-02-20) + (00:47 - 14:19)
= (24 hours) + (-(47 mins + 41 mins + 9 hours))
= (24 hours) - (10:28)
= 14 hours - 28 mins
= 13 hours 32 mins from broadcast to confirmation.
Log in to LocalBitcoins.
Browse to Wallet / Transactions.
Most recent transaction:
- Date = 02/21/2019 01:00
- Received BTC = 0.00283894
- Sent BTC =
- Description = Deposit to 36zGvt......
- Deposit Fee BTC = 0.00015000
Good. Deposit confirmed.
So, the experiment is finished. I have successfully created a transaction with two outputs and paid for it to be added to the Bitcoin blockchain. I have transferred the bitcoin stored in the outputs back to my LocalBitcoins account.
I made some alterations in create_nonstandard_transaction.py that I'd like to also add to create_transaction.py.
I'll rewrite create_transaction.py and test that, when given the same input data, it still produces tx_1 (although without the spurious addition of the hash type at the end, this time).
The work directory containing create_nonstandard_transaction.py is called "work3". I'll take the state of the dependencies in this directory as the new state.
Copy create_transaction.py to work3 directory.
[development occurs here]
I've also made some changes to create_nonstandard_transaction.py. I'll re-run and test it as well.
Assemble the information for tx_1 again:
Transaction tx_1:
Input data:
- txid (of the previous transaction tx_0 that transferred the unspent output to the input address):
f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
- previous_output_index (the index of this unspent output in the previous transaction):
12
-- Note: From the output list of tx_0, I found that the output sent to 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj appears in the thirteenth position in the output list.
- private key (of the input address):
7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5
-- Note: This is the private key for the source address 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
- input amount (amount contained in the unspent output):
0.006 bitcoin (600000 satoshi)
- 32-byte random value (in this case, entropy_1):
257c2ff4ac1606d5e42fe152c2624cffac2aa58cdfe8578a69b12beefbce68b9
output 1 (to destination address 1):
- destination address:
1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- amount: 0.003 bitcoin (300000 satoshi)
output 2 (to destination address 2):
- destination address:
1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- amount: 0.003 bitcoin (300000 satoshi)
The fee rate was originally 3 satoshi / byte. However, the transaction size estimation has changed slightly (due to the removal of the hash type byte). Hm. The original final fee was 774 satoshi, so I'll set the fee to that amount for this run.
aineko:work3 stjohnpiano$ python create_transaction.py
### START CREATION OF BITCOIN TRANSACTION
- Fee type: fee
- Fee: 774 (satoshi)
- Number of inputs (i.e. as-yet-unspent outputs): 1
- Number of outputs: 2
- Change address: 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- Amount to be sent to the change address: 0.003
- Input addresses, with total-value-to-be-sent:
-- 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj: 0.00600000
- Output addresses, with total-value-to-be-received:
-- 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig: 0.00300000
-- 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P: 0.00300000
- Total value of all inputs: 0.00600000
- Total value of all outputs: 0.00600000
- Total value of all inputs exactly matches total value of all outputs.
- Estimated transaction size: 257 bytes
- Final fee: 774 (satoshi)
- Final fee rate (using estimated transaction size): 3.0117 (satoshi per byte)
- Fee subtracted from amount-to-be-sent-to-change-address.
- New amount to be sent to change address: 299226 (satoshi)
- Size of signed transaction: 257 bytes
- (signed_tx_size - estimated_tx_size): 0 bytes
- Fee rate in signed transaction: 3.012 (satoshi / byte)
Input 0:
Input: {40 bytes unsigned, 66 bytes signable, 179 bytes signed}
- [data] previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
- [data] previous_output_index: 0c000000 (4 bytes)
- [signed form] script_length: 8a (1 bytes)
- [signed form] scriptSig: 47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a (138 bytes)
- [data] sequence: ffffffff (4 bytes)
- [used for signing] private_key_hex: 7972b641101c0ad67b0e401b800a9b6f3225c97fc6b8115042cf66968c2fb2e5 (32 bytes)
- [destination, goes into scriptSig] public_key_hex: 04108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a (65 bytes)
- [signable form] script_length_scriptPubKey: 19 (1 bytes)
- [signable form] scriptPubKey: 76a91438a1681a09280ecb20b62cf661913e811eb3c4b188ac (25 bytes)
- [more info] address: 16ASCUS3s7D4UQh6J9oHGuT19agPvD3PFj
- [more info] previous_output_index_int: 12
- [more info] txid: f02eca2852bf73f3c722db2d151e7755d853efd8dd6224249b14f8b51dffbc6e
Output 0:
Output: {34 bytes}
- [data] value: e093040000000000 (8 bytes)
- [data] script_length: 19 (1 bytes)
- [data] scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- [more info] address: 1KHDLNmqBtiBELUsmTCkNASg79jfEVKrig
- [more info] bitcoin_amount: 0.003
- [more info] satoshi_amount: 300000
- [more info] public_key_hash_hex: c8833727be832b6634d8ddf7bfcf51e379b28f63
Output 1:
Output: {34 bytes}
- [data] value: da90040000000000 (8 bytes)
- [data] script_length: 19 (1 bytes)
- [data] scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- [more info] address: 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P
- [more info] bitcoin_amount: 0.00299226
- [more info] satoshi_amount: 299226
- [more info] public_key_hash_hex: 875a093668adff783d0835f4db655c5a47a0ceaa
Transaction (unsigned form): {118 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {40 bytes}
-- previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
-- previous_output_index: 0c000000 (4 bytes)
-- script_length: [none] (0 bytes)
-- scriptSig: [none] (0 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 02 (1 bytes)
- Output 0: {34 bytes}
-- value: e093040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- Output 1: {34 bytes}
-- value: da90040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- block_lock_time: 00000000 (4 bytes)
Transaction (signable form 0): {148 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0 [to be used to sign this signable form]: {66 bytes}
-- previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
-- previous_output_index: 0c000000 (4 bytes)
-- script_length_scriptPubKey: 19 (1 bytes)
-- scriptPubKey: 76a91438a1681a09280ecb20b62cf661913e811eb3c4b188ac (25 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 02 (1 bytes)
- Output 0: {34 bytes}
-- value: e093040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- Output 1: {34 bytes}
-- value: da90040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- block_lock_time: 00000000 (4 bytes)
- hash_type_4_byte: 01000000 (4 bytes)
Transaction (signed form): {257 bytes}
- version: 01000000 (4 bytes)
- input_count: 01 (1 bytes)
- Input 0: {179 bytes}
-- previous_output_hash: 6ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef0 (32 bytes)
-- previous_output_index: 0c000000 (4 bytes)
-- script_length: 8a (1 bytes)
-- scriptSig: 47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2a (138 bytes)
-- sequence: ffffffff (4 bytes)
- output_count: 02 (1 bytes)
- Output 0: {34 bytes}
-- value: e093040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914c8833727be832b6634d8ddf7bfcf51e379b28f6388ac (25 bytes)
- Output 1: {34 bytes}
-- value: da90040000000000 (8 bytes)
-- script_length: 19 (1 bytes)
-- scriptPubKey: 76a914875a093668adff783d0835f4db655c5a47a0ceaa88ac (25 bytes)
- block_lock_time: 00000000 (4 bytes)
Signed transaction:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000
### END CREATION OF BITCOIN TRANSACTION
new tx_1:
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000
original tx_1 (without the hash type byte at the end):
01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000
Test for equality:
[new tx_1]
[original tx_1 (without hash type at the end]
equal
aineko:work3 stjohnpiano$ s1="01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000"
[original tx_1 (without hash type at the end]
aineko:work3 stjohnpiano$ s1="01000000016ebcff1db5f8149b242462ddd8ef53d855771e152ddb22c7f373bf5228ca2ef00c0000008a47304402202d8617427fc589848ef2e0481d148e0ce5d60aaa26e466fdfe62890d0d67ca6902200df89728ea73816cecfdfd6a734ca8b70da7000e213b87dcfdc9d48400164fac014104108e1c01a42bbd09b77a26b5f732f10d7108b2fe31cba137e9d15e24c7c30d2515904dfe646f3e94a3aa482afbbe0dc178b9b212154529768e0ba74452df1c2affffffff02e0930400000000001976a914c8833727be832b6634d8ddf7bfcf51e379b28f6388acda900400000000001976a914875a093668adff783d0835f4db655c5a47a0ceaa88ac00000000"
aineko:work3 stjohnpiano$ [[ "$s1" = "$s2" ]] && echo equal || echo not-equal
equal
Excellent.
Perform the same test process for tx_2 (tx_2b) and tx_3.
original tx_2 (tx_2b):
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
new tx_2:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Equality test shows that they're equal.
original tx_3:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
new tx_3:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Equality test shows that they're equal.
Excellent.
Next: Test which files in the whole toolset have been changed.
Create new work directory "work4".
Browse to:
Recipe for creating and signing a standard Bitcoin transaction
Download all assets and move them to the work4 directory.
List of assets:
- bitcoin_functions.py
- bjorn_edstrom_ripemd160.py
- create_transaction.py
- ecdsa-0.10.tar.gz
- pypy_sha256.py
- transaction.py
Unpack the ecdsa-0.10.tar.gz asset, using the following command:
tar -zxvf ecdsa-0.10.tar.gz
This unpacking should produce a new directory named "ecdsa-0.10" in the work directory. The directory "ecdsa-0.10" should contain a directory named "ecdsa". Copy the "ecdsa" directory into the work directory.
Browse to:
Recipe for creating and signing a nonstandard Bitcoin transaction
List of assets:
- bitcoin_functions.py
- bjorn_edstrom_ripemd160.py
- create_nonstandard_transaction.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions.py
- nonstandard_transaction.py
- pypy_sha256.py
- transaction.py
Download this sublist of the assets and move them to the work directory.
- create_nonstandard_transaction.py
- nonstandard_bitcoin_functions.py
- nonstandard_transaction.py
Combined list:
- bitcoin_functions.py
- bjorn_edstrom_ripemd160.py
- create_nonstandard_transaction.py
- create_transaction.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions.py
- nonstandard_transaction.py
- pypy_sha256.py
- transaction.py
Test for differences:
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ ls -1
items
notes.txt
tmp.txt
tmp2.txt
to_do.txt
work
work2
work3
work4
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/bitcoin_functions.py work4/bitcoin_functions.py | wc -l
16
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/bjorn_edstrom_ripemd160.py work4/bjorn_edstrom_ripemd160.py | wc -l
0
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/create_nonstandard_transaction.py work4/create_nonstandard_transaction.py | wc -l
461
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/create_transaction.py work4/create_transaction.py | wc -l
450
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff -r work3/ecdsa work4/ecdsa
Only in work3/ecdsa: __init__.pyc
Only in work3/ecdsa: _version.pyc
Only in work3/ecdsa: curves.pyc
Only in work3/ecdsa: der.pyc
Only in work3/ecdsa: ecdsa.pyc
Only in work3/ecdsa: ellipticcurve.pyc
Only in work3/ecdsa: keys.pyc
Only in work3/ecdsa: numbertheory.pyc
Only in work3/ecdsa: rfc6979.pyc
Only in work3/ecdsa: six.pyc
Only in work3/ecdsa: util.pyc
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/ecdsa-0.10.tar.gz work4/ecdsa-0.10.tar.gz | wc -l
0
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/nonstandard_bitcoin_functions.py work4/nonstandard_bitcoin_functions.py | wc -l
0
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/nonstandard_transaction.py work4/nonstandard_transaction.py | wc -l
221
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/pypy_sha256.py work4/pypy_sha256.py | wc -l
0
aineko:creating_a_bitcoin_transaction_with_two_outputs stjohnpiano$ diff work3/transaction.py work4/transaction.py | wc -l
249
The compiled bytecode files (*.pyc) can be ignored.
The files for which
diff
output 0 lines do not have be added as assets to this article. The files for which
diff
output at least 1 line must be renamed and added as assets to this article. These are:
- bitcoin_functions.py
- create_nonstandard_transaction.py
- create_transaction.py
- nonstandard_transaction.py
- transaction.py
Renamed:
- bitcoin_functions_2.py
- create_nonstandard_transaction_2.py
- create_transaction_2.py
- nonstandard_transaction_2.py
- transaction_2.py
Rename the files in work3, not work4.
If they are renamed, the
import
commands in some files must be changed. These are not imported:
- create_nonstandard_transaction_2.py
- create_transaction_2.py
These are imported:
- bitcoin_functions_2.py
- nonstandard_transaction_2.py
- transaction_2.py
Files that do the importing:
- create_nonstandard_transaction_2.py
- create_transaction_2.py
- nonstandard_transaction_2.py
- transaction_2.py
So, in the files that do the importing, change the import commands to use the new names of the changed files.
Now, run create_transaction_2.py and test that it produces the same tx_1 as before.
Done. Equality test shows that the result is as expected. The importing works.
create_nonstandard_transaction_2.py is currently set to produce tx_2 (tx_2b). Run it and test that the result is the same as before.
Done. Equality test shows that the result is as expected. The importing works.
Asset list for this article:
- bitcoin_functions_2.py
- create_nonstandard_transaction_2.py
- create_transaction_2.py
- nonstandard_transaction_2.py
- transaction_2.py
Note: nonstandard_bitcoin_functions.py still imports bitcoin_functions.py (i.e. version 1 of bitcoin_functions.py).
Let's summarise the hash type problem that I found earlier in
- nonstandard_transaction.py
- transaction.py
Looking at these files in work4 (the original versions), I find that:
- The hash type (SIGHASH_ALL) is 1. As 1 byte, this is 0x01. As 4 bytes (little-endian), this is 0x01 00 00 00. The 4-byte version is appended to the transaction-in-signable-form before signing. The 1-byte version is appended to the signature_data after signing.
-- These steps are implemented in the code.
- However, I made a mistake in the original code. The hash type (4-byte version) is also appended to the final signed form of the transaction. This occurs in:
-- Transaction.get_signed_form() [transaction.py: line 289]
-- Transaction.get_description_of_signed_form() [transaction.py: line 312]
-- NonstandardTransaction.get_signed_form() [nonstandard_transaction.py: line 237]
-- NonstandardTransaction.get_description_of_signed_form() [nonstandard_transaction.py: line 269]
- To fix the problem, delete these lines.
I'll quote the lines here:
- Transaction.get_signed_form() [transaction.py: line 289]
s += self.hash_type_4_byte
- Transaction.get_description_of_signed_form() [transaction.py: line 312]
s += "\n- hash_type_4_byte: %s" % self.hash_type_4_byte
- NonstandardTransaction.get_signed_form() [nonstandard_transaction.py: line 237]
s += self.hash_type_4_byte
- NonstandardTransaction.get_description_of_signed_form() [nonstandard_transaction.py: line 269]
s += "\n- hash_type_4_byte: %s" % self.hash_type_4_byte
Ok. Next: Cleanup.
Create a new directory: "assets"
Copy the assets from work3 into the assets directory.
Assets:
- bitcoin_functions_2.py
- create_nonstandard_transaction_2.py
- create_transaction_2.py
- nonstandard_transaction_2.py
- transaction_2.py
Delete the work directories:
- work
- work2
- work3
- work4
That's the end of this project.
[start of notes]
Changes from the original text:
- I have not always preserved the format of any excerpts from webpages on other sites (e.g. not preserving the original bold/italic styles, changing the list structures, not preserving hyperlinks).
- I have not always preserved the format of any computer output (e.g. from running bash commands). Examples: Setting input lines in bold text, adding/removing newlines in order to make a sequence of commands easier to read, using hyphens for lists and sublists instead of indentation, breaking wide tables into consecutive sections.
[end of notes]
It's actually: 774 / 257 ~= 3.01167