Transaction Chains
Overview
Basic Transaction Chain
import { Transaction, PrivateKey, P2PKH, BEEF } from '@bsv/sdk'
/**
* Basic Transaction Chain Builder
*
* Create a simple chain of transactions where each transaction
* spends outputs from the previous transaction.
*/
class TransactionChainBuilder {
/**
* Create a chain of transactions
*
* @param privateKey - Private key to sign transactions
* @param initialUTXO - Starting UTXO
* @param chainLength - Number of transactions in the chain
* @param amountPerTx - Amount to transfer in each transaction
* @returns Array of chained transactions
*/
async buildSimpleChain(
privateKey: PrivateKey,
initialUTXO: {
txid: string
vout: number
satoshis: number
script: Script
},
chainLength: number,
amountPerTx: number
): Promise<Transaction[]> {
try {
if (chainLength < 2) {
throw new Error('Chain length must be at least 2')
}
const chain: Transaction[] = []
let currentUTXO = initialUTXO
for (let i = 0; i < chainLength; i++) {
const tx = new Transaction()
// Add input from previous transaction (or initial UTXO)
tx.addInput({
sourceTXID: currentUTXO.txid,
sourceOutputIndex: currentUTXO.vout,
unlockingScriptTemplate: new P2PKH().unlock(privateKey),
sequence: 0xffffffff
})
// Calculate fee
const fee = 500
// Validate sufficient funds
if (currentUTXO.satoshis < amountPerTx + fee) {
throw new Error(`Insufficient funds at chain position ${i}`)
}
// Add output for next transaction in chain
const outputScript = new P2PKH().lock(privateKey.toPublicKey().toHash())
tx.addOutput({
satoshis: amountPerTx,
lockingScript: outputScript
})
// Add change output if needed
const change = currentUTXO.satoshis - amountPerTx - fee
if (change > 546) {
tx.addOutput({
satoshis: change,
lockingScript: outputScript
})
}
// Sign transaction
await tx.sign()
chain.push(tx)
// Update current UTXO for next iteration
currentUTXO = {
txid: tx.id('hex'),
vout: 0,
satoshis: amountPerTx,
script: outputScript
}
console.log(`Created transaction ${i + 1}/${chainLength} in chain`)
}
return chain
} catch (error) {
throw new Error(`Transaction chain building failed: ${error.message}`)
}
}
/**
* Create a branching chain (one input, multiple outputs, each spent separately)
*/
async buildBranchingChain(
privateKey: PrivateKey,
initialUTXO: {
txid: string
vout: number
satoshis: number
script: Script
},
branches: number
): Promise<{ root: Transaction; branches: Transaction[] }> {
try {
const outputScript = new P2PKH().lock(privateKey.toPublicKey().toHash())
// Create root transaction with multiple outputs
const rootTx = new Transaction()
rootTx.addInput({
sourceTXID: initialUTXO.txid,
sourceOutputIndex: initialUTXO.vout,
unlockingScriptTemplate: new P2PKH().unlock(privateKey),
sequence: 0xffffffff
})
// Calculate amount per branch
const fee = 500 + (branches * 50)
const amountPerBranch = Math.floor((initialUTXO.satoshis - fee) / branches)
if (amountPerBranch < 546) {
throw new Error('Not enough satoshis for branches')
}
// Create outputs for each branch
for (let i = 0; i < branches; i++) {
rootTx.addOutput({
satoshis: amountPerBranch,
lockingScript: outputScript
})
}
await rootTx.sign()
// Create branch transactions
const branchTxs: Transaction[] = []
for (let i = 0; i < branches; i++) {
const branchTx = new Transaction()
branchTx.addInput({
sourceTXID: rootTx.id('hex'),
sourceOutputIndex: i,
unlockingScriptTemplate: new P2PKH().unlock(privateKey),
sequence: 0xffffffff
})
const branchFee = 500
const branchOutput = amountPerBranch - branchFee
branchTx.addOutput({
satoshis: branchOutput,
lockingScript: outputScript
})
await branchTx.sign()
branchTxs.push(branchTx)
}
console.log(`Created branching chain: 1 root → ${branches} branches`)
return { root: rootTx, branches: branchTxs }
} catch (error) {
throw new Error(`Branching chain creation failed: ${error.message}`)
}
}
}
/**
* Usage Example
*/
async function basicChainExample() {
const builder = new TransactionChainBuilder()
const privateKey = PrivateKey.fromWif('your-wif-key')
const initialUTXO = {
txid: 'initial-txid...',
vout: 0,
satoshis: 100000,
script: new P2PKH().lock(privateKey.toPublicKey().toHash())
}
// Create a chain of 5 transactions
const chain = await builder.buildSimpleChain(privateKey, initialUTXO, 5, 15000)
console.log('Chain created:')
chain.forEach((tx, i) => {
console.log(` ${i + 1}. ${tx.id('hex')}`)
})
}BEEF Format Transaction Chain
Advanced Chain Patterns
Chain Validation and Management
Related Examples
See Also
Last updated
