--- id: txbuilder title: TxBuilder Example --- Bitcoin-S features a transaction building API that allows you to construct and sign Bitcoin transactions. Here's an example of how to use it ```scala mdoc:invisible import scala.concurrent._ import scala.concurrent.duration._ import org.bitcoins.core._ import number._ import config._ import currency._ import org.bitcoins.crypto._ import script.crypto._ import protocol.transaction._ import protocol.script._ import wallet.builder._ import wallet.fee._ import wallet.utxo._ ``` ```scala mdoc:to-string implicit val ec: ExecutionContext = ExecutionContext.Implicits.global // Initialize a transaction builder val builder = RawTxBuilder() // generate a fresh private key that we are going to use in the scriptpubkey val privKey = ECPrivateKey.freshPrivateKey val pubKey = privKey.publicKey // this is the script that the TxBuilder is going to create a // script signature that validly spends this scriptPubKey val creditingSpk = P2PKHScriptPubKey(pubKey = privKey.publicKey) val amount = 10000.satoshis // this is the UTXO we are going to be spending val utxo = TransactionOutput(value = amount, scriptPubKey = creditingSpk) // the private key that locks the funds for the script we are spending too val destinationPrivKey = ECPrivateKey.freshPrivateKey // the amount we are sending -- 5000 satoshis -- to the destinationSPK val destinationAmount = 5000.satoshis // the script that corresponds to destination private key, this is what is receiving the money val destinationSPK = P2PKHScriptPubKey(pubKey = destinationPrivKey.publicKey) // this is where we are sending money too // we could add more destinations here if we // wanted to batch transactions val destinations = { val destination0 = TransactionOutput(value = destinationAmount, scriptPubKey = destinationSPK) Vector(destination0) } // Add the destinations to the tx builder builder ++= destinations // we have to fabricate a transaction that contains the // UTXO we are trying to spend. If this were a real blockchain // we would need to reference the UTXO set val creditingTx = BaseTransaction(version = Int32.one, inputs = Vector.empty, outputs = Vector(utxo), lockTime = UInt32.zero) // this is the information we need from the crediting TX // to properly "link" it in the transaction we are creating val outPoint = TransactionOutPoint(creditingTx.txId, UInt32.zero) val input = TransactionInput( outPoint, EmptyScriptSignature, sequenceNumber = UInt32.zero) // Add a new input to our builder builder += input // We can now generate a RawTxBuilderResult ready to be finalized val builderResult = builder.result() // this contains the information needed to analyze our input during finalization val inputInfo = P2PKHInputInfo(outPoint, amount, privKey.publicKey) // this is how much we are going to pay as a fee to the network // for this example, we are going to pay 1 satoshi per byte val feeRate = SatoshisPerByte(1.satoshi) val changePrivKey = ECPrivateKey.freshPrivateKey val changeSPK = P2PKHScriptPubKey(pubKey = changePrivKey.publicKey) // We chose a finalizer that adds a change output to our tx based on a fee rate val finalizer = NonInteractiveWithChangeFinalizer( Vector(inputInfo), feeRate, changeSPK) // We can now finalize the tx builder result from earlier with this finalizer val unsignedTxF: Future[Transaction] = finalizer.buildTx(builderResult) // We now turn to signing the unsigned transaction // this contains all the information we need to // validly sign the UTXO above val utxoInfo = ScriptSignatureParams(inputInfo = inputInfo, signers = Vector(privKey), hashType = HashType.sigHashAll) // all of the UTXO spending information, since we only have // one input, this is just one element val utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(utxoInfo) // Yay! Now we use the RawTxSigner object to sign the tx. // The 'sign' method is going produce a validly signed transaction // This is going to iterate through each of the UTXOs and use // the corresponding ScriptSignatureParams to produce a validly // signed input. This UTXO has: // 1: one input // 2: outputs (destination and change outputs) // 3: a fee rate of 1 satoshi/byte val signedTx: Transaction = { val signedTxF = unsignedTxF.flatMap { unsignedTx => RawTxSigner.sign( utx = unsignedTx, utxoInfos = utxoInfos, expectedFeeRate = feeRate ) } Await.result(signedTxF, 30.seconds) } ``` ```scala mdoc:to-string signedTx.inputs.length signedTx.outputs.length //remember, you can call .hex on any bitcoin-s data structure to get the hex representation! signedTx.hex ```