Given a raw, standard Tx (wiki):






and a private key:


How does one construct a new transaction to redeem the coin from the second output? I've been trying to figure this out for a long while using etotheipi's diagram, but can't seem to grasp how a proper transaction is to be created. A step-by-step guide would be welcome.

  • in bitcoind, I used the resulting hex to do this signrawtransaction '0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2010000008a4730440220359f19e3d19dd707053641ff1efd0ca25159d0e0a8cbe13cbdcf38a9608c38ee02207383ebc663253a21101597ed897366e2a748ab29c18a8ca183d02910283e88cc01410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6ffffffff01605af405000000001976a914097072524438d003d23a2f23edb65aae1bb3e46988ac00000000' '[]' '[]' And it returned me 'false' ... I think there is a problem with the code ? – user7295 Nov 7 '13 at 5:34
  • 1
    @Daniel, i'm not certain, but this might be because bitcoind signrawtransaction requires a real previous output transaction in the blockchain in order to calculate the funds? the hash for the transaction given in this question is f2b3eb2deb76566e7324307cd47c35eeb88413f971d88519859b1834307ecfec, which says does not exist – mulllhausen Dec 25 '13 at 1:06
  • @mulllhausen How was this done if the txid is wrong? – Wizard Of Ozzie Nov 21 '14 at 3:40
up vote 71 down vote accepted

In this answer, I will go through the steps necessary to redeem the second output of the transaction listed above. The answer will be limited to redeeming an output of the particular type present in this transaction (an output which requires providing a new transaction signed with a private key whose corresponding public key hashes to the hash in the script of the output in question), as this answer is already fairly long, even without taking into account other output types.

Short summary: We begin by constructing a new transaction, with a scriptSig containing the scriptPubKey of the output we want to redeem. The scriptPubKey of this transaction will contain a script that pays to a hash of a public key (Bitcoin address). We perform a double-SHA256 hash on this transaction with the four-byte hash code type SIGHASH_ALL appended to the end. We sign this hash with the private key supplied above. The scriptSig of this new transaction is then replaced with a script that first pushes the DER-encoded signature, plus the one-byte hash code type SIGHASH_ALL, to the stack, followed by the DER-encoded private key's corresponding public key.

Step-by-step description:

We start creating a new raw transaction which we hash and sign.

  1. Add four-byte version field: 01000000
  2. One-byte varint specifying the number of inputs: 01
  3. 32-byte hash of the transaction from which we want to redeem an output: eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
  4. Four-byte field denoting the output index we want to redeem from the transaction with the above hash (output number 2 = output index 1): 01000000
  5. Now comes the scriptSig. For the purpose of signing the transaction, this is temporarily filled with the scriptPubKey of the output we want to redeem. First we write a one-byte varint which denotes the length of the scriptSig (0x19 = 25 bytes): 19
  6. Then we write the temporary scriptSig which, again, is the scriptPubKey of the output we want to redeem: 76a914010966776006953d5567439e5e39f86a0d273bee88ac
  7. Then we write a four-byte field denoting the sequence. This is currently always set to 0xffffffff: ffffffff
  8. Next comes a one-byte varint containing the number of outputs in our new transaction. We will set this to 1 in this example: 01
  9. We then write an 8-byte field (64 bit integer) containing the amount we want to redeem from the specified output. I will set this to the total amount available in the output minus a fee of 0.001 BTC (0.999 BTC, or 99900000 Satoshis): 605af40500000000
  10. Then we start writing our transaction's output. We start with a one-byte varint denoting the length of the output script (0x19 or 25 bytes): 19
  11. Then the actual output script: 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac
  12. Then we write the four-byte "lock time" field: 00000000
  13. And at last, we write a four-byte "hash code type" (1 in our case): 01000000

    We now have the following raw transaction data:

  14. (signing stage) Now we double-SHA256 hash this entire structure, which yields the hash 9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e

  15. We then create a public/private key pair out of the provided private key. We sign the hash from step 14 with the private key, which yields the following DER-encoded signature (this signature will be different in your case): 30460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc06 To this signature we append the one-byte hash code type: 01. The public key is: 0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6
  16. We construct the final scriptSig by concatenating:

    • One-byte script OPCODE containing the length of the DER-encoded signature plus 1 (the length of the one-byte hash code type)
    • The actual DER-encoded signature plus the one-byte hash code type
    • One-byte script OPCODE containing the length of the public key
    • The actual public key
  17. We then replace the one-byte, varint length-field from step 5 with the length of the data from step 16. The length is 140 bytes, or 0x8C bytes: 8c

  18. And we replace the temporary scriptSig from Step 6 with the data structure constructed in step 16. This becomes: 4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6
  19. We finish off by removing the four-byte hash code type we added in step 13, and we end up with the following stream of bytes, which is the final transaction:


Python example code:

I have created an example Python script which does all the above. It is intentionally as verbose as possible, and heavily commented, with as few functions as possible, in order to resemble the step-by-step guide above. The number of code lines can easily be reduced to one half, but I choose to post it in this verbose format as I judge that it's the easiest to follow (ie. no 'jumping' backwards and forwards through functions). The script contains 76 non-empty, non-comment lines. The script depends on Gavin Andresen's bitcointools (for serializing and deserializing transactions, and base58 encoding/decoding) and from my fork of joric's brutus repository (for constructing public/private EC key pairs and ECDSA signing). The easiest way to get the script to run is to clone bitcointools into a folder, and put from the above URL in the same folder along with this script, and executing the script from there. You will want to replace the address in the SEND_TO_ADDRESS variable in this script with the address you want the coins sent to, unless you're feeling generous :).

from deserialize import parse_Transaction, opcodes
from BCDataStream import BCDataStream
from base58 import bc_address_to_hash_160, b58decode, public_key_to_bc_address, hash_160_to_bc_address

import ecdsa_ssl

import Crypto.Hash.SHA256 as sha256
import Crypto.Random

#transaction, from which we want to redeem an output
#output to redeem. must exist in HEX_TRANSACTION
#address we want to send the redeemed coins to.
#REPLACE WITH YOUR OWN ADDRESS, unless you're feeling generous 
#fee we want to pay (in BTC)
#constant that defines the number of Satoshis per BTC
#constant used to determine which part of the transaction is hashed.
#private key whose public key hashes to the hash contained in scriptPubKey of output number *OUTPUT_INDEX* in the transaction described in HEX_TRANSACTION

def dsha256(data):


#here we use bitcointools to parse a transaction. this gives easy access to the various fields of the transaction from which we want to redeem an output
stream = BCDataStream()
tx_info = parse_Transaction(stream)

if len(tx_info['txOut']) < (OUTPUT_INDEX+1):
   raise RuntimeError, "there are only %d output(s) in the transaction you're trying to redeem from. you want to redeem output index %d" % (len(tx_info['txOut']), OUTPUT_INDEX)

#this dictionary is used to store the values of the various transaction fields
#  this is useful because we need to construct one transaction to hash and sign
#  and another that will be the final transaction
tx_fields = {}

##here we start creating the transaction that we hash and sign
sign_tx = BCDataStream()
##first we write the version number, which is 1
tx_fields['version'] = 1
##then we write the number of transaction inputs, which is one
tx_fields['num_txin'] = 1

##then we write the actual transaction data
tx_fields['prevout_hash'] = tx_hash
sign_tx.write(tx_fields['prevout_hash']) #hash of the the transaction from which we want to redeem an output
tx_fields['output_index'] = OUTPUT_INDEX
sign_tx.write_uint32(tx_fields['output_index']) #which output of the transaction with tx id 'prevout_hash' do we want to redeem?

##next comes the part of the transaction input. here we place the script of the *output* that we want to redeem
tx_fields['scriptSigHash'] = tx_info['txOut'][OUTPUT_INDEX]['scriptPubKey']
#first write the size
#then the data

tx_fields['sequence'] = 0xffffffff

##then we write the number of transaction outputs. we'll just use a single output in this example
tx_fields['num_txout'] = 1
##then we write the actual transaction output data
#we'll redeem everything from the original output minus TX_FEE
tx_fields['value'] = tx_info['txOut'][OUTPUT_INDEX]['value']-(TX_FEE*COIN)
##this is where our scriptPubKey goes (a script that pays out to an address)
#we want the following script:
address_hash = bc_address_to_hash_160(SEND_TO_ADDRESS)
#chr(20) is the length of the address_hash (20 bytes or 160 bits)
scriptPubKey = chr(opcodes.OP_DUP) + chr(opcodes.OP_HASH160) + \
   chr(20) + address_hash + chr(opcodes.OP_EQUALVERIFY) + chr(opcodes.OP_CHECKSIG)
#first write the length of this lump of data
tx_fields['scriptPubKey'] = scriptPubKey
#then the data

#write locktime (0)
tx_fields['locktime'] = 0
#and hash code type (1)
tx_fields['hash_type'] = SIGHASH_ALL

#then we obtain the hash of the signature-less transaction (the hash that we sign using our private key)
hash_scriptless = dsha256(sign_tx.input)

##now we begin with the ECDSA stuff.
## we create a private key from the provided private key data, and sign hash_scriptless with it
## we also check that the private key's corresponding public key can actually redeem the specified output

k = ecdsa_ssl.KEY()
k.generate(('%064x' % PRIVATE_KEY).decode('hex'))

#here we retrieve the public key data generated from the supplied private key
pubkey_data = k.get_pubkey()
#then we create a signature over the hash of the signature-less transaction
#a one byte "hash type" is appended to the end of the signature (
sig_data = sig_data + chr(SIGHASH_ALL)

#let's check that the provided privat key can actually redeem the output in question
if (bc_address_to_hash_160(public_key_to_bc_address(pubkey_data)) != tx_info['txOut'][OUTPUT_INDEX]['scriptPubKey'][3:-2]):
   bytes = b58decode(SEND_TO_ADDRESS, 25)
   raise RuntimeError, "The supplied private key cannot be used to redeem output index %d\nYou need to supply the private key for address %s" % \
                           (OUTPUT_INDEX, hash_160_to_bc_address(tx_info['txOut'][OUTPUT_INDEX]['scriptPubKey'][3:-2], bytes[0]))

##now we begin creating the final transaction. this is a duplicate of the signature-less transaction,
## with the scriptSig filled out with a script that pushes the signature plus one-byte hash code type, and public key from above, to the stack

final_tx = BCDataStream()

##now we need to write the actual scriptSig.
## this consists of the DER-encoded values r and s from the signature, a one-byte hash code type, and the public key in uncompressed format
## we also need to prepend the length of these two data pieces (encoded as a single byte
## containing the length), before each data piece. this length is a script opcode that tells the
## Bitcoin script interpreter to push the x following bytes onto the stack

scriptSig = chr(len(sig_data)) + sig_data + chr(len(pubkey_data)) + pubkey_data
#first write the length of this data
#then the data

##and then we simply write the same data after the scriptSig that is in the signature-less transaction,
#  leaving out the four-byte hash code type (as this is encoded in the single byte following the signature data)


#prints out the final transaction in hex format (can be used as an argument to bitcoind's sendrawtransaction)
print final_tx.input.encode('hex')
  • 2
    Are you sure step 11 is correct? It just shows the origin address. Shouldn't that be a script like "OP_DUP OP_HASH160 destination_address_in_hash_160_format OP_EQUALVERIFY OP_CHECKSIG"? Where OP_DUP is replaced with "76", etc, as described here. – Sjors Provoost May 10 '13 at 16:42
  • 1
    I'm stuck at step 15... Any idea what I might be doing wrong?… – Sjors Provoost May 10 '13 at 20:54
  • Regarding my first comment, I just noticed that the address is indeed wrapped in 76 a9 and 88 ac. So it sends everything back to the origin. – Sjors Provoost May 11 '13 at 8:49
  • No it doesn't send it back, it sends it to 1runeksijzfVxyrpiyCY2LCBvYsSiFsCm. – Sjors Provoost May 11 '13 at 9:29
  • 1
    Pardon my lack of knowledge but is it normal that the script gives different results every time it is run ? I didn't know there a need for random number generation when creating a transfer (?) – user7295 Oct 27 '13 at 2:17

This gist, partially based on the answer by Runeks, shows how to transfer 0.01 bitcoins in Ruby. It fetches information from the previous transaction from, so you just need to feed it your private key and address (the latter being redundant but useful for the demonstration). I added a lot of comments to explain the steps involved.

Once you know the Transaction ID, the vout, the scriptPubKey of that transaction, and the WIF encoded private key corresponding to the public key hashed to yield the address, you can create a raw transaction, and sign it, without being online.

I have written a PHP library to deal with raw transactions (amongst other bitcoin functionality). Here's how you would redeem a regular transaction: It needs an update to support P2SH signatures, but it'll redeem a regular transaction just fine.

protected by Community May 29 '14 at 21:30

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.