mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-26 15:42:49 +01:00
Added OutputReference and introduced public key computation on SPKs Made InputInfo into an ADT Made UTXOSpendingInfo use InputInfo Replaced UTXOSpendingInfo with NewSpendingInfo and got non-test things compiling Made aliases for (NewSpendingInfo/NewSpendingInfoFull/NewSpendingInfoSingle)[InputInfo] Got rid of source code mention of UTXOSpendingInfo sbt compile passes tests compile Fixed all coreTest tests Renamed to UTXOInfo Some cleanup Moved redeem script and script witness accessors to companion object Responded to code review Added OutputReference and scaladocs Moved p2pkhPreImageOpt downstream and generalized to hashPreImages Fixed adding-spks.md Fixed psbts.md and txbuilder.md Renamed UTXOInfo Apply renaming to docs
4.7 KiB
4.7 KiB
id | title |
---|---|
txbuilder | TxBuilder Example |
Bitcoin-S features a transaction builder that constructs and signs Bitcoin transactions. Here's an example of how to use it
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._
implicit val ec: ExecutionContext = ExecutionContext.Implicits.global
// 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 protecting 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 destination1 = TransactionOutput(value = destinationAmount,
scriptPubKey = destinationSPK)
Vector(destination1)
}
// 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)
// this contains all the information we need to
// validly sign the UTXO above
val utxoInfo = ScriptSignatureParams(inputInfo = InputInfo(outPoint = outPoint,
output = utxo,
redeemScriptOpt = None,
scriptWitnessOpt = None,
conditionalPath =
ConditionalPath.NoCondition,
hashPreImages = Vector(privKey.publicKey)),
signers = Vector(privKey),
hashType =
HashType.sigHashAll)
// all of the UTXO spending information, since we are only
//spending one UTXO, this is just one element
val utxos: Vector[ScriptSignatureParams[InputInfo]] = Vector(utxoInfo)
// 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)
// the network we are on, for this example we are using
// the regression test network. This is a network you control
// on your own machine
val networkParams = RegTest
// Yay! Now we have a TxBuilder object that we can use
// to sign the TX.
val txBuilder: BitcoinTxBuilder = {
val builderF = BitcoinTxBuilder(
destinations = destinations,
utxos = utxos,
feeRate = feeRate,
changeSPK = changeSPK,
network = networkParams)
Await.result(builderF, 30.seconds)
}
// Let's finally produce a validly signed 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 signF = txBuilder.sign
Await.result(signF, 30.seconds)
}
signedTx.inputs.length
signedTx.outputs.length
//remember, you can call .hex on any bitcoin-s data structure to get the hex representation!
signedTx.hex