edgecase_datafeed 70 2018-11-16 This is the date at the time of creation of this datafeed article. A checkpoint article containing a hash of this datafeed article may be created on this date or at a later date. 62 7 2018-10-01 bitcoin 8b53df721231f95e4e1843a74fd560fcfd6512d2e258ba1a2fc0472a8230b467 543904 33jEsi2kqFwMtagFqBuHuzCeYPVdDkR8zP 1DaAgMor4bZiAuLgZWdz4W5RkoYVQFvDKp
Recipe_for_creating_and_signing_a_standard_Bitcoin_transaction stjohn_piano 2018-11-15 no Parts - Description - Assets - Notes - Recipe - Example Description This recipe describes a method of creating and signing a standard Bitcoin transaction with one input and one output. This transaction will authorise the transfer of an "unspent output" stored at one address to a second address, minus a transaction fee. This unspent output contains a particular value of bitcoin and must be transferred completely in the transaction. Assets Asset: A library of functions for handling standard Bitcoin data types. asset_of_another_article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 bitcoin_functions.py bitcoin_functions.py e6d2c81e26c5dc0171a4489e78e5457c58559bc4a76bf5147e63224323672c1a Asset: An implementation of RIPEMD-160, written by B_j_o:r_n_ E_d_s_t_r_o:m_. asset_of_another_article Reading_and_verifying_a_standard_raw_bitcoin_transaction edgecase 51 bjorn_edstrom_ripemd160.py bjorn_edstrom_ripemd160.py a5ca6eb289989861e30806ff7e39165622bd366a1c6cd5edd2dbd7dfc4877666 Asset: A script that creates and signs a standard Bitcoin transaction with one input and one output. asset_of_another_article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 create_transaction.py create_transaction.py 973c2015927b5b28d9d852c05b95b1005b70212bd8f5e80e8b0ee53457cabb2d Asset: A Python implementation of ECDSA cryptography, written by Peter Pearson. asset_of_another_article Reading_and_verifying_a_standard_raw_bitcoin_transaction edgecase 51 ecdsa-0.10.tar.gz ecdsa-0.10.tar.gz 67dae9e1af2b0fd71bc9a378654f7dc89211c1c5aee71e160f8cfce1fa6d6980 Asset: A Python implementation of SHA256. asset_of_another_article Reading_and_verifying_a_standard_raw_bitcoin_transaction edgecase 51 pypy_sha256.py pypy_sha256.py 2bbd4a83b69625e2f7ece5201475af2803f0ea11f3815c83d8afab3773d8f47b Asset: A library of classes for standard Bitcoin transactions. asset_of_another_article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 transaction.py transaction.py a9911c246aae1b6777de9bf1b932e1716f68bba5f9d43ac3c9822d25d1477d45 Notes 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. My working definition of a standard address: - An uncompressed single-signature Pay-To-Public-Key-Hash (P2PKH) address. Standard addresses start with the character '1'. The code used in this recipe only supports transactions with one standard input and one standard output. A standard input spends bitcoin from a standard address. A standard output sends bitcoin to a standard address. This recipe assumes that you already have a Bitcoin address and have transferred some bitcoin to it. If not, the following article describes how to generate a Bitcoin address: article Recipe_for_generating_a_Bitcoin_address edgecase 69 Recipe for generating a Bitcoin address This recipe was originally published in the article article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 Creating and signing a standard raw Bitcoin transaction: Iteration #2 , in the section Recipes For Using Various Downloadable Assets, in the part "Recipe 3: create_transaction.py". The recipe shown here has been edited for republication. Several points concerning Bitcoin transactions: - New transactions spend unspent-outputs-of-previous-transactions. - The bitcoin balance of an address is the sum of the unspent outputs sent by previous transactions to this address. - To spend bitcoin from an address, the bitcoin amount must be constructed from complete unspent outputs. Any change can be sent in a new unspent output back to the original address or another that you control. Unspent outputs cannot be broken into smaller unspent outputs prior to spending - new unspent outputs (larger or smaller) must be created by a new transaction. Recipe Definitions: - input address: the address that currently contains the bitcoin that you want to transfer in this transaction. - output address: the address to which the bitcoin will be transferred by this transaction. - previous_output_hash: big-endian 32-byte double-SHA256 hash of a previous transaction. - txid: "transaction id", the little-endian form of the previous_output_hash. Initial conditions: - You must have Python 2.7.x installed on your computer. These code assets were developed / tested under Python 2.7.13 running on Mac OS X 10.6.8 (Snow Leopard), and should run successfully on other versions of Python 2.7. - You must already have a Bitcoin address and the corresponding Bitcoin private key (ideally 32 bytes long). A 32-byte private key will be 64 hex characters long. When used as a control value in this recipe, it must be a 64-character string that consists only of hex characters (the ten digit characters "0123456789" and the lower-case alphabetical characters "abcdef"). - You will need 32 bytes of entropy (per input, but in this recipe there is only 1 input). The following article describes one way to generate this entropy: article Recipe_for_generating_entropy_bytes_using_dice edgecase 67 Recipe for generating entropy bytes using dice . Every ECDSA signature you ever make should use a different random value. Ideally this random value should be 32 bytes long. 1 byte is represented by 2 hex characters, so a 32-byte random value will be 64 hex characters long. When used in this recipe, the random value must be a 64-character string that consists only of hex characters (the ten digit characters "0123456789" and the lower-case alphabetical characters "abcdef"). 1) Gather the following pieces of information: - The txid of the previous transaction that transferred the unspent output to the input address. - The index of this unspent output in the previous transaction (the "previous_output_index"). This index is implicit and starts at zero, and can be found by examining the list of outputs in the previous transaction, and looking for the particular unspent output that you wish to transfer. - The private key (in hex bytes) of the input address. - The bitcoin amount (or satoshi amount) contained within the unspent output. Let's call this the "input amount". - A 32-byte random value (1 per input), as listed in the initial conditions. The transaction will be signed once using each input and each signature requires 32 bytes of entropy. 2) Choose the following pieces of information: - The output address. - The bitcoin amount (or satoshi amount) that you wish to transfer to the output address. Let's call this the "output amount". Note: This should be equal to the input amount (the code does not have the ability to send change). - The change address. Any value not assigned to an output address will be assigned to the change address. The fee will be subtracted from the final value assigned to the change address. Note: This must be the same as the output address. Since, in this recipe, the change address is the same as the only output address, the fee will always be subtracted from the value assigned to the single output address. - The fee (in satoshi) or fee_rate (in satoshi / byte). The fee must be an integer e.g. "225". The fee_rate must be an integer e.g. "1" or a float e.g. "1.2". Note: You should look up the range of fee rates for transactions that are currently being mined. 3) Create a work directory. 4) Browse to the Assets part of this article and download all the linked assets. List of assets: - bitcoin_functions.py - bjorn_edstrom_ripemd160.py - create_transaction.py - ecdsa-0.10.tar.gz - pypy_sha256.py - transaction.py 5) Move these assets into the work directory. 6) Unpack the zipped tape archive file ecdsa-0.10.tar.gz. This can be done by opening a terminal, changing directory to the work directory, and running 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. 7) Open the file create_transaction.py in a text editor. Scroll to lines 44-68, which should be the section of text that lies between ##### START CONTROLS and ##### END CONTROLS Note: In create_transaction.py, all control values are strings (i.e. are contained within quotation marks). 8) Set the variable random_value to the 32-byte random value. 9) Set the variable random_value_type to "hex_bytes". 10) The variable input_data is a dictionary that contains several other variables. - Set the value of the variable input_data["txid"] to be the txid. - Set the value of the variable input_data["previous_output_index"] to be the index of the unspent output. - Set the value of the variable input_data["private_key_hex"] to be the private key. - If the input amount is in satoshi, set the value of the variable input_data["satoshi_amount"] to be the input amount. - If the input amount is in bitcoin, set the value of the variable input_data["bitcoin_amount"] to be the input amount. Note: Currently, if both of the variables input_data["satoshi_amount"] and input_data["bitcoin_amount"] are set, then input_data["bitcoin_amount"] will take precedence. You can comment out the unused variable of the pair by placing a number sign ('#') at the start of the relevant line. 11) The variable output_data is a dictionary that contains several other variables. - Set the value of the variable output_data["address"] to be the output address. - If the output amount is in satoshi, set the value of the variable output_data["satoshi_amount"] to be the output amount. - If the output amount is in bitcoin, set the value of the variable output_data["bitcoin_amount"] to be the output amount. Note: Currently, if both of the variables output_data["satoshi_amount"] and output_data["bitcoin_amount"] are set, output_data["bitcoin_amount"] will take precedence. You can comment out the unused variable of the pair by placing a number sign ('#') at the start of the relevant line. 12) Set the variable change_address to be the change address. 13) If you have chosen to set the fee as an absolute number of satoshi, set the variable fee to be the fee amount and set the variable fee_type to be "fee". 14) If you have chosen to set the fee as a fee rate (in satoshi / byte), set the variable fee_rate to be the fee rate and set the variable fee_type to be "fee_rate". 15) Open a terminal and change directory to the work directory. 16) Run the following command: python create_transaction.py At the end, the output should contain the signed transaction as a hex byte sequence without spaces. Example I'm going to attempt to replicate tx1 from the article article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 Creating and signing a standard raw Bitcoin transaction: Iteration #2 . In the linked article, I can see the information gathered / chosen in order to create tx1: Source address: - Private key (raw bytes): "the_mote_in_god's_eye" - Private key (hex bytes): 7468655f6d6f74655f696e5f676f6427735f657965 - Bitcoin address: 138obEZkdWaWEQ4x8ZAYw4MybHSZtX1Nam - Current balance: 0.00242 BTC Target address: - Private key (raw bytes): "roadside_picnic" - Bitcoin address: 13xPBB175FtPbPQ84iB8KuawaVy3mHrady Previous transaction containing the unspent output that I wish to spend: - txid: e4609e0f1ca854b8b07381f32ba31adbad9713205f5a4f3f56a5a32853d47855 - previous_output_hash: 5578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4 - previous_output_index: 8 - scriptPubKey of relevant unspent output from previous transaction: 76a914176a0e0c2b9b0e77d630712ad301b749102a304488ac Value of unspent output: - 0.00242 btc Value to send to output address: - 0.002 btc - Random value (raw bytes): "The Face of God dhcmrlchtdj" fee_rate = 1 (satoshi / byte) I'll convert the random value to hex bytes. - Random value (hex bytes): 5468652046616365206f6620476f64206468636d726c636874646a Note: "Value to send to output address" is set to be less than the unspent output value in order to demonstrate that any unassigned value will be sent to the change address. Note: During the project shown in the linked article, I used raw byte private keys for convenience. The input address's private key was converted to hex byte form so that it could be used as a control value. It is only 21 bytes long. For serious use, the private key should be 32 bytes long and generated from a high-quality entropy source. This note also applies to the random value (which is only 27 bytes long here). Let's put these gathered / chosen values into the order described within the recipe: Gathered: - txid: e4609e0f1ca854b8b07381f32ba31adbad9713205f5a4f3f56a5a32853d47855 - previous_output_index: 8 - private key (hex bytes): 7468655f6d6f74655f696e5f676f6427735f657965 - input amount (bitcoin): 0.00242 - 32-byte random value (only 27 bytes long in this case): 5468652046616365206f6620476f64206468636d726c636874646a Chosen: - output address: 13xPBB175FtPbPQ84iB8KuawaVy3mHrady - output amount (bitcoin): 0.002 - change address: 13xPBB175FtPbPQ84iB8KuawaVy3mHrady - fee_rate (satoshi / byte): 1 Follow the recipe. Open the file create_transaction.py in a text editor. Scroll to lines 44-68, which is the section of text that lies between ##### START CONTROLS and ##### END CONTROLS As shown in the recipe, set the relevant variables to contain the gathered / chosen control values. Results: create_transaction.py python_2.7.13 yes 43 ##### START CONTROLS # Note: Hex characters in input variable values must be lowercase. random_value = "5468652046616365206f6620476f64206468636d726c636874646a" # random_value must be between 1 and 32 bytes. If random_value_type is "raw_bytes", then random_value must be between 1 and 32 ASCII characters. If random_value_type is "hex_bytes", then random_value must be an even number of hex characters and between 2 and 64 hex characters (1 byte is represented by 2 hex characters). # Note: Every ECDSA signature (one for each input in a transaction) requires new random entropy. # random_value_type options: ["raw_bytes", "hex_bytes"] random_value_type = "hex_bytes" input_data = { "txid": "e4609e0f1ca854b8b07381f32ba31adbad9713205f5a4f3f56a5a32853d47855", "previous_output_index": "8", "private_key_hex": "7468655f6d6f74655f696e5f676f6427735f657965", #"satoshi_amount": "242000", "bitcoin_amount": "0.00242", } output_data = { "address": "13xPBB175FtPbPQ84iB8KuawaVy3mHrady", #"satoshi_amount": "200000", "bitcoin_amount": "0.002", } # note: all inputs and outputs are assumed to be Pay-To-Public-Key-Hash (P2PKH). change_address = "13xPBB175FtPbPQ84iB8KuawaVy3mHrady" # note: the fee will be subtracted from the amount that is being sent to the change address. fee = "223" # satoshi fee_rate = "1" # satoshi / byte # fee_type options: ["fee", "fee_rate"] fee_type = "fee_rate" ##### END CONTROLS Now run the script. This is a demonstration of creating a signed transaction that authorises a specified transfer of bitcoin. aineko:work stjohnpiano$ python create_transaction.py ### START CREATION OF 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: 13xPBB175FtPbPQ84iB8KuawaVy3mHrady - Amount to be sent to the change address: 0.002 - Input addresses, with total-value-to-be-sent: -- 138obEZkdWaWEQ4x8ZAYw4MybHSZtX1Nam: 0.00242000 - Output addresses, with total-value-to-be-received: -- 13xPBB175FtPbPQ84iB8KuawaVy3mHrady: 0.00200000 - Total value of all inputs: 0.00242000 - Total value of all outputs: 0.00200000 - Total value of all inputs is greater than total value of all outputs. -- Some input value has not been assigned to an output. -- Extra value: 0.00042000 -- This extra value will be sent to the change address. -- Change address: 13xPBB175FtPbPQ84iB8KuawaVy3mHrady -- New amount to be sent to change address: 0.00242000 - Estimated transaction size: 223 bytes - Fee rate: 1.0 (satoshi / byte) - Calculate 223 * 1.0 and round up to nearest satoshi. - Final fee: 223 (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: 241777 (satoshi) Input 0: Input (without signature): - previous_output_hash: 5578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4 - previous_output_index: 08000000 - sequence: ffffffff - private_key_hex: 00000000000000000000007468655f6d6f74655f696e5f676f6427735f657965 - public_key_hex: 041ad06846fd7cf9998a827485d8dd5aaba9eccc385ba7759a6e9055fbdf90d7513c0d11fe5e5dcfcf8d4946c67f6c45f8e7f7d7a9c254ca8ebde1ffd64ab9dd58 - script_length_scriptPubKey: 19 - scriptPubKey: 76a914176a0e0c2b9b0e77d630712ad301b749102a304488ac - script_length: None - scriptSig: None - address: 138obEZkdWaWEQ4x8ZAYw4MybHSZtX1Nam - previous_output_index_int: 8 - txid: e4609e0f1ca854b8b07381f32ba31adbad9713205f5a4f3f56a5a32853d47855 Output 0: Output: - value: 71b0030000000000 - script_length: 19 - scriptPubKey: 76a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac - address: 13xPBB175FtPbPQ84iB8KuawaVy3mHrady - bitcoin_amount: 0.00241777 - satoshi_amount: 241777 - public_key_hash_hex: 2069a3fae01db74cef12d1d01811afdf6a3e1c2e Transaction (unsigned form): - version: 01000000 - input_count: 01 - Input: -- previous_output_hash: 5578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4 -- previous_output_index: 08000000 -- script_length: None -- scriptSig: None -- sequence: ffffffff - output_count: 01 - Output: -- value: 71b0030000000000 -- script_length: 19 -- scriptPubKey: 76a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac - block_lock_time: 00000000 Transaction (signable form): - version: 01000000 - input_count: 01 - Input [to be used to sign this signable form]: -- previous_output_hash: 5578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4 -- previous_output_index: 08000000 -- script_length_scriptPubKey: 19 -- scriptPubKey: 76a914176a0e0c2b9b0e77d630712ad301b749102a304488ac -- sequence: ffffffff - output_count: 01 - Output: -- value: 71b0030000000000 -- script_length: 19 -- scriptPubKey: 76a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac - block_lock_time: 00000000 - hash_type_4_byte: 01000000 Transaction (signed form): - version: 01000000 - input_count: 01 - Input: -- previous_output_hash: 5578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4 -- previous_output_index: 08000000 -- script_length: 8a -- scriptSig: 473044022017ece35581a034a4838a577fe438f108cf22764927a1ad197ed379460c0764cd022066723723eff05c10bac9a2f63b3e782e24fde290701c9408f3d1054722adad360141041ad06846fd7cf9998a827485d8dd5aaba9eccc385ba7759a6e9055fbdf90d7513c0d11fe5e5dcfcf8d4946c67f6c45f8e7f7d7a9c254ca8ebde1ffd64ab9dd58 -- sequence: ffffffff - output_count: 01 - Output: -- value: 71b0030000000000 -- script_length: 19 -- scriptPubKey: 76a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac - block_lock_time: 00000000 - hash_type_4_byte: 01000000 Signed transaction: 01000000015578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4080000008a473044022017ece35581a034a4838a577fe438f108cf22764927a1ad197ed379460c0764cd022066723723eff05c10bac9a2f63b3e782e24fde290701c9408f3d1054722adad360141041ad06846fd7cf9998a827485d8dd5aaba9eccc385ba7759a6e9055fbdf90d7513c0d11fe5e5dcfcf8d4946c67f6c45f8e7f7d7a9c254ca8ebde1ffd64ab9dd58ffffffff0171b00300000000001976a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac0000000001000000 ### END CREATION OF BITCOIN TRANSACTION The final signed transaction is: 01000000015578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4080000008a473044022017ece35581a034a4838a577fe438f108cf22764927a1ad197ed379460c0764cd022066723723eff05c10bac9a2f63b3e782e24fde290701c9408f3d1054722adad360141041ad06846fd7cf9998a827485d8dd5aaba9eccc385ba7759a6e9055fbdf90d7513c0d11fe5e5dcfcf8d4946c67f6c45f8e7f7d7a9c254ca8ebde1ffd64ab9dd58ffffffff0171b00300000000001976a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac0000000001000000 I'll confirm that this is identical to the original signed tx1 that was broadcast in the previous project. [original tx1] aineko:work stjohnpiano$ s1="01000000015578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4080000008a473044022017ece35581a034a4838a577fe438f108cf22764927a1ad197ed379460c0764cd022066723723eff05c10bac9a2f63b3e782e24fde290701c9408f3d1054722adad360141041ad06846fd7cf9998a827485d8dd5aaba9eccc385ba7759a6e9055fbdf90d7513c0d11fe5e5dcfcf8d4946c67f6c45f8e7f7d7a9c254ca8ebde1ffd64ab9dd58ffffffff0171b00300000000001976a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac0000000001000000" [newly-calculated tx1] aineko:work stjohnpiano$ s2="01000000015578d45328a3a5563f4f5a5f201397addb1aa32bf38173b0b854a81c0f9e60e4080000008a473044022017ece35581a034a4838a577fe438f108cf22764927a1ad197ed379460c0764cd022066723723eff05c10bac9a2f63b3e782e24fde290701c9408f3d1054722adad360141041ad06846fd7cf9998a827485d8dd5aaba9eccc385ba7759a6e9055fbdf90d7513c0d11fe5e5dcfcf8d4946c67f6c45f8e7f7d7a9c254ca8ebde1ffd64ab9dd58ffffffff0171b00300000000001976a9142069a3fae01db74cef12d1d01811afdf6a3e1c2e88ac0000000001000000" aineko:work stjohnpiano$ [[ "$s1" = "$s2" ]] && echo equal || echo not-equal equal Excellent. They're identical. I've followed the recipe, using the same inputs, and have re-created the signed transaction from the previous project.
iQIcBAABCgAGBQJb7qpNAAoJECL1OzZgiBhwXigP/Ar2aE+3M3Aeuc8ImBwoBVU3 5BPOvrcXEoc5dMwcD4FVr9H44cCO7AAcnor5vq+Q8s4vTnG2xUUttUv6ACFAnJFQ urNz4nDfpfCwD8kLFdSsZ4ky0akfZlgcASPD2zB8WZ//VuUgbezfQKYtpkZEdApk cMAkz0qWz22GPcmS7HiBacnw5cOTLskLWPHun4auBGYt7iMjhw6AH6p3FRKZkLur zSxIPgrdI/HxZI2qUh3/2BOpaOn1roVg7mlOuNc8o6xXzL8Rd/YbMNSAoTZtgl1x GENNJ1YpMfRIXcsl2dipR8qmkHjAaidWqNLnZDV/Mk7DxgsVUjORz/J5x3jIBLoX Lm3/pS0t/PShrbTXTYNDkF5rblwiIpqWo/4WBidC29WBaQ4z6Vrra6J8QrnD5wW8 AdV5d6a/iXDv6EcRVEHflrJiAkyQ/i2RpvzBmc7QHONT64TGIhZp1nNt45S1L0JM KNEY84CrSREAZCWbFMVAIjC3tfLqLxj++3yiQno1AERxYKX2Swk3u5oI7/o8RwGi 2/C3eN/MiQ25szV0TOnzkDWE9baCMqU1cfC+Y2dxBBbbrJchjKpEbDSo7j5B0MtD EPqMSBTt7vCju/SjJmhkca5HTb8M1ve9FYKe81kxAWQimFXFnov87mj0sv6rHs1a FFcHZ3UzfRHP/cpLE5lt =OMxI