Parts
- Description
- Assets
- Notes
- Recipe
- Examples
Description
This recipe describes a method of creating and signing a nonstandard Bitcoin transaction with at least one standard P2PKH input and at least one output. An output can be standard P2PKH or nonstandard P2SH.
This recipe was written for Edgecase Bitcoin Storage Toolset version 2. It includes links to the specific assets that it uses.
Each input is an "unspent output" that is stored at a particular address. When the transaction is mined, this unspent output is "spent". Each output of the transaction is a new "unspent output".
Various combinations of inputs and outputs are possible. For example, a transaction can have 3 inputs and 2 outputs.
Assets
Asset: A library of functions for handling standard Bitcoin data types.
bitcoin_functions_2.py [paywalled]
Asset: An implementation of RIPEMD-160, written by Björn Edström.
bjorn_edstrom_ripemd160.py [paywalled]
Asset: A script that creates and signs a nonstandard Bitcoin transaction with at least one standard P2PKH input and at least one output. An output can be standard P2PKH or nonstandard P2SH.
create_nonstandard_transaction_3.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_2.py [paywalled]
Asset: A library of classes for nonstandard Bitcoin transactions.
nonstandard_transaction_3.py [paywalled]
Asset: A Python implementation of SHA256.
pypy_sha256.py [paywalled]
Asset: A library of classes for standard Bitcoin transactions.
transaction_3.py [paywalled]
Notes
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.
Working definition of a nonstandard transaction:
- It has at least one input and at least one output.
- At least one input or output address is not a standard Pay-To-Public-Key-Hash (P2PKH) address.
The code used in this recipe only supports nonstandard transactions with at least one standard P2PKH input and at least one output. An output can be standard P2PKH or nonstandard P2SH. Nonstandard inputs are not supported.
A standard input spends bitcoin from a standard address. A nonstandard output sends bitcoin to a nonstandard address.
Standard addresses start with the character '1'. Example:
1AGygbyEFYduWkkmZbbvirgS9kuBBMLJCP
begins with a '1' and is therefore a standard P2PKH address.
Example of a nonstandard address:
- A Pay-To-Script-Hash (P2SH) address.
Pay-To-Script-Hash (P2SH) addresses begin with the character '3'. Example:
The address
328cTqexYnQRbN5Dgs12D89sYiPPvtWVbF
begins with a '3' and is therefore a P2SH address.
Previous version of this recipe:
Recipe for creating and signing a nonstandard Bitcoin transaction
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.
- A transaction fee is not a strict requirement, but in practice your transaction is unlikely to be mined without one.
- The transaction will be signed with the private key of each source address. Each signature will be stored with the relevant input in the transaction.
Recipe
Definitions:
- Source address: The address that currently contains some bitcoin that you want to transfer in this transaction.
- Destination address: The address to which some bitcoin will be transferred by this transaction.
- Previous output hash: Big-endian 32-byte double-SHA256 hash of a previous transaction.
- Tx: "transaction".
- Txid: "transaction id". The little-endian form of the previous output hash.
- Previous output index: The index of an unspent output in the onchain transaction that created it. This index is implicit and starts at zero, and can be found by examining the list of outputs in the transaction, and finding the position of the specific unspent output in question.
Initial conditions:
- You must have Python 2.7.x installed on your computer. The code used in this recipe has been run in Python 2.7.5 on CentOS 7.6 and in Python 2.7.13 on Mac OS X 10.6.8. It should run successfully in Python 2.7.x.
- For each input, you will need to generate 32 bytes of entropy. The transaction will be signed once using each input and each signature requires 32 bytes of entropy. The following article describes one way to generate this entropy: Recipe for generating entropy bytes using dice #2. Every ECDSA signature you ever make should use a different random 32-byte value.
Notes on hex values:
- All byte sequences are written in hex when supplied as input or printed as output.
- 1 byte is written as 2 hex characters. A 32-byte sequence is therefore 64 characters in hex.
- Hex characters consist of the ten digit characters "0123456789" and the lower-case alphabetical characters "abcdef".
1) Source details.
For each input, gather the following pieces of information:
- Txid: The txid of the previous transaction that transferred the unspent output to the source address.
- Previous output index: The index of this unspent output in the previous transaction.
- Private key: The 32-byte private key of the source address.
- Input amount: The amount contained within the unspent output. This can be a bitcoin value or a satoshi value.
- Random value: A 32-byte random value.
2) Destination details.
Choose the following pieces of information:
- Destination addresses, their type ("p2pkh" or "p2sh"), and the amount to be sent to each one.
- Change address. If there is a difference between the total input value and the total output value, this difference will be sent to the change address. The transaction fee will be subtracted from the amount assigned to the change address.
- Fee or fee rate. A fee value is in satoshi and a fee_rate value is in satoshi / byte. 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_2.py
- bjorn_edstrom_ripemd160.py
- create_nonstandard_transaction_3.py
- ecdsa-0.10.tar.gz
- nonstandard_bitcoin_functions_2.py
- nonstandard_transaction_3.py
- pypy_sha256.py
- transaction_3.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_nonstandard_transaction.py in a text editor. Scroll to lines 42-85, which should be the section of text that lies between
##### START CONTROLS
and
##### END CONTROLS
Note: In create_nonstandard_transaction.py, all control values are strings (i.e. are contained within quotation marks).
8) Set the list variable
random_values
to contain the 32-byte random values, one for each input. The first random value will be used to make the first input's signature, the second will be used to make second's signature, and so on.9) Set the variable
random_value_type
to
"hex_bytes"
. 10) The variable
input_data
is a list that contains dictionaries. Each dictionary contains the data for one input. For each input dictionary:
- Set the value of the
"txid"
key to be the txid. - Set the value of the
"previous_output_index"
key to be the previous output index. - Set the value of the
"private_key_hex"
key to be the private key. - If the input amount is in satoshi, set the value of the
"satoshi_amount"
key to be the input amount. - If the input amount is in bitcoin, set the value of the
"bitcoin_amount"
key to be the input amount. Note: If both of the
"satoshi_amount"
and
"bitcoin_amount"
keys are supplied, then
"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.- Set the value of the
"input_type"
key to be
"p2pkh"
. 11) The variable
output_data
is a list that contains dictionaries. Each dictionary contains the data for one output. For each output:
- Set the value of the
"address"
key to be the output address.- If the output amount is in satoshi, set the value of the
"satoshi_amount"
key to be the output amount.- If the output amount is in bitcoin, set the value of the
"bitcoin_amount"
key to be the output amount.Note: If both of the
"satoshi_amount"
and
"bitcoin_amount"
keys are set, then
"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. - Set the value of the
"output_type"
key to be the address's type. This will be either
"p2pkh"
or
"p2sh"
. 12) Set the variable
change_address
to be the change address.13) Set the fee or fee rate.
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"
. The fee must be an integer e.g.
"225"
. Otherwise, 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"
. The fee_rate must be an integer e.g.
"1"
or a float e.g.
"1.2"
. 14) Open a terminal and change directory to the work directory.
15) Run the following command:
python create_nonstandard_transaction_3.py
At the end, the output will contain the signed transaction as a hex byte sequence without spaces.
Examples
I'm going to replicate Transactions "tx_2b" and "tx_3" from Bitcoin nonstandard transaction test set. Both transactions have 1 standard P2PKH input and 1 nonstandard P2SH output.
Machine details:
- Windows 10
- Windows Subsystem for Linux (WSL): Ubuntu 16.04
- I'm working in the WSL Ubuntu terminal.
I've created a work directory (named "work"), downloaded the assets, and moved them into the work directory.
Transaction tx_2b:
I know from the transaction details that the actual output amount was 0.00299668 bitcoin, but I'm going to set it to be the same as the input amount (0.003 bitcoin), to demonstrate that the script will correctly subtract the fee (332 satoshi) from the input amount.
Source details:
- Input 1:
-- Txid:
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
-- Previous output index:
0
-- Private key:
d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85
-- Input amount:
0.003 bitcoin
-- Random value:
11964601ab4e0f24d09509ad2b72a11cedb079cbc723cea092a3dc9ca36429d7
Destination details:
- Addresses, types, and amounts:
-- 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU (p2sh): 0.003 bitcoin
- Change address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- Fee:
332 satoshi
Expected result: Signed version of Transaction tx_2b:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Plug these values into the controls in create_nonstandard_transaction_3.py, as shown below:
##### START CONTROLS | |
random_values = [ | |
"11964601ab4e0f24d09509ad2b72a11cedb079cbc723cea092a3dc9ca36429d7", | |
] | |
# 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. | |
# 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": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4", | |
"previous_output_index": "0", | |
"private_key_hex": "d45941cae4e31c824b041407053c9c15624e6234f9649bfd7d5bb5a93c53fe85", | |
#"satoshi_amount": "", | |
"bitcoin_amount": "0.003", | |
"input_type": "p2pkh", | |
}, | |
] | |
output_data = [ | |
{ | |
"address": "36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU", | |
#"satoshi_amount": "", | |
"bitcoin_amount": "0.003", | |
"output_type": "p2sh", | |
}, | |
] | |
change_address = "36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU" | |
# note: the fee will be subtracted from the amount that is being sent to the change address. | |
fee = "332" # satoshi | |
fee_rate = "" # satoshi / byte | |
# fee_type options: ["fee", "fee_rate"] | |
fee_type = "fee" | |
##### END CONTROLS |
Run the script.
stjohn@judgement:work$ python create_nonstandard_transaction_3.py
### START CREATION OF NONSTANDARD BITCOIN TRANSACTION
- Fee type: fee
- Fee: 332 (satoshi)
- 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.003
- 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
- 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)
- [source, 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
Compare the result with the expected result.
stjohn@judgement:work$ expected="0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000"
stjohn@judgement:work$ result="0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb000000008b483045022100aadd9eaf24a0f1741c712670ca661081b7e6af0b7d02e22377d5e9dc27a92f2f022005720a2a3c72bd62b819627d4220d8cdeff132a97e61e9a87e33ac88af3749a0014104876224f0d418523de3770a2b5d7ce071932227fbf9f760f788b038edf04d5e6029903f6251a3e13701790982677209703b424411af8ee1cc86b8e992a568a363ffffffff01949204000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000"
stjohn@judgement:work$ [[ "$expected" = "$result" ]] && echo equal || echo not-equal
equal
Good. The new transaction matches the original one.
Transaction tx_3:
This time, I assign the exact final output value to the output address. The additional value in the input address will be assigned to the output address, and then will be subtracted to pay the transaction fee.
Source details:
- Input 1:
-- Txid:
db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4
-- Previous output index:
1
-- Private key:
1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27
-- Input amount:
0.00299226 bitcoin
-- Random value:
7b088a64007d9d3b06d74ed15d92d6abe7b2796d5e3c4b8c3eebc51aab4576b5
Destination details:
- Addresses, types, and amounts:
-- 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU (p2sh): 0.00298894 bitcoin
- Change address:
36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
- Fee:
332 satoshi
Expected result: Signed version of Transaction tx_3:
0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000
Plug these values into the controls in create_nonstandard_transaction_3.py, as shown below:
##### START CONTROLS | |
random_values = [ | |
"7b088a64007d9d3b06d74ed15d92d6abe7b2796d5e3c4b8c3eebc51aab4576b5", | |
] | |
# 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. | |
# 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": "db2c3d84708cd9d0e40ae1754021f9146a0d6ab555fc0e1d547d7876c0c092f4", | |
"previous_output_index": "1", | |
"private_key_hex": "1faf3c86105fe6ee328b29e94197de7e8500ddb8308385a9a8b0cba08d59ce27", | |
#"satoshi_amount": "", | |
"bitcoin_amount": "0.00299226", | |
"input_type": "p2pkh", | |
}, | |
] | |
output_data = [ | |
{ | |
"address": "36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU", | |
#"satoshi_amount": "", | |
"bitcoin_amount": "0.00298894", | |
"output_type": "p2sh", | |
}, | |
] | |
change_address = "36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU" | |
# note: the fee will be subtracted from the amount that is being sent to the change address. | |
fee = "332" # satoshi | |
fee_rate = "" # satoshi / byte | |
# fee_type options: ["fee", "fee_rate"] | |
fee_type = "fee" | |
##### END CONTROLS |
Run the script.
stjohn@judgement:work$ python create_nonstandard_transaction_3.py
### START CREATION OF NONSTANDARD BITCOIN TRANSACTION
- Fee type: fee
- Fee: 332 (satoshi)
- 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.00298894
- Input addresses, with total-value-to-be-sent:
-- 1DLg5i1kBjXYXy9f82xZcHokEMC9dtct7P: 0.00299226
- Output addresses, with total-value-to-be-received:
-- 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU: 0.00298894
- Total value of all inputs: 0.00299226
- Total value of all outputs: 0.00298894
- 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.00000332
-- This extra value will be sent to the change address.
-- Change address: 36zGvt8hkRXFnp2S97ARKTLuwqWx5E9ozU
-- New amount to be sent to change address: 0.00299226
- Estimated transaction size: 221 bytes
- 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)
- [source, 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
Compare the result with the expected result.
stjohn@judgement:work$ expected="0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000"
stjohn@judgement:work$ result="0100000001f492c0c076787d541d0efc55b56a0d6a14f9214075e10ae4d0d98c70843d2cdb010000008a47304402207d68b7bc903cd351ecfe5e69943d701e432ec6a7983e00af963299b1f67e43e9022025cbfd3b684292da7f1c69fb1d3fdf2d5a4f88a7d19c3a9aabd5ed8b3a6458890141040f46f336b1fca05f244d8d3fd651de5e0afc1ed8412b17026e7fa6f31e2854089277313988737a980bffdb67d8a01a374b9e6ab880b506dfe132ab81721976e7ffffffff018e8f04000000000017a9143a1c39fcbfd4a1407deddf47249bbfccb12a74788700000000"
stjohn@judgement:work$ [[ "$expected" = "$result" ]] && echo equal || echo not-equal
equal
Good. The new transaction matches the original one.
Excellent. That's the end of the project.