Transactions

Figure 1: Transaction Inputs and Outputs

Figure 1: Transaction Inputs and Outputs

Be sure to review the section on Bitcoin Script from the Developer Guide.

Creating a Transaction

Transactions never stand in isolation. Every new transaction we create must “spend from” another, existing transaction. Referring to the above diagram:

In order to construct a Transaction [c1], we need to do the following:

  1. Obtain a copy of Transaction [b1]
  2. Obtain the Output Script (aka scriptPubKey) in the Output of Transaction [b1] (marked in orange)
  3. Create an Input Script (aka scriptSig) in the Input of Transaction [c1] (marked in blue)

(1) Obtaining a Transaction to spend from

One can obtain the Transaction to spend from in any of a number of ways. These include:

  • Quering the Merchant API of a service provider (e.g. WhatsOnchain)
  • Have it passed directly to you by a counter party

For our purposes, we will assume that we have the following Transaction, serialised in hexadecimal to act as our Transaction [b1]

val b1Hex = "01000000015884e5db9de218238671572340b207ee85b628074e7e467096c267266baf77a4000000006a473044022013fa3089327b50263029265572ae1b022a91d10ac80eb4f32f291c914533670b02200d8a5ed5f62634a7e1a0dc9188a3cc460a986267ae4d58faf50c79105431327501210223078d2942df62c45621d209fab84ea9a7a23346201b7727b9b45a29c4e76f5effffffff0150690f00000000001976a9147821c0a3768aa9d1a37e16cf76002aef5373f1a888ac00000000"

(2) Obtain the Output to spend from


val fundingTx = Transaction.fromHex(b1Hex)

//let's assume we are spending the first output in the list
val utxo: TransactionOutput  = fundingTx.outputs[0]

(3) Create the spending Transaction

We now use a TransactionBuilder to construct the spending transaction.


/*
  our new transaction [c1] will contain an Output Script. The coins in that script
  will be locked using an address of our choosing. We use a P2PKHLockBuilder
  to help us construct a canonical P2PKH locking script.
 */

//assume we have a wif private key to import
val pkOne = PrivateKey.fromWIF("L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m")

//In order to create our spending Input Script in Transaction *[c1]* we use
//another utility (P2PKHUnlockBuilder), to help us construct the unlocking/spending script.
val unlocker = P2PKHUnlockBuilder(pkOne.publicKey)


//create a recipient to send the money to
val recipientAddress = Address.fromKey(NetworkAddressType.MAIN_PKH, pkOne.publicKey)


//construct a LockingScriptBuilder that will generate the P2PKH locking script
val locker = P2PKHLockBuilder(recipientAddress)


//create a TransactionSigner that will be invoked to sign our spending transaction
val txSigner = TransactionSigner(SigHashType.ALL.value or SigHashType.FORKID.value, pkOne)


val txBuilder = TransactionBuilder()
          .spendFromTransaction(txSigner, fundingTx, 0, TransactionInput.MAX_SEQ_NUMBER, unlocker)
          .spendTo(locker, BigInteger.valueOf(200000))
          .sendChangeTo(recipientAddress)  //send change to recipient too !
          .withFeePerKb(512)

//Build the transaction, which will invoke signing operations automatically
val broadcastTx: Transaction = txBuilder.build(true)

//serialise our tx ready for network broadcast
val txHex = HEX.encode(broadcastTx.serialize())