Script Templates
Standard and custom Bitcoin script patterns available in the BSV TypeScript SDK.
What are Script Templates?
Script templates provide reusable patterns for Bitcoin transaction locking and unlocking scripts:
import { P2PKH } from '@bsv/sdk'
// Use a standard template
const template = new P2PKH()
// Create locking script
const lockingScript = template.lock(publicKeyHash)
// Create unlocking script
const unlockingScript = template.unlock(privateKey, signature)
Standard Templates
P2PKH (Pay to Public Key Hash)
The most common Bitcoin script pattern:
const p2pkh = new P2PKH()
const lock = p2pkh.lock(publicKeyHash)
const unlock = p2pkh.unlock(privateKey, signature)
P2PK (Pay to Public Key)
Direct payment to a public key:
OP_RETURN (Data Storage)
Store arbitrary data on-chain:
const opReturn = new OpReturn()
const lock = opReturn.lock(data)
// No unlock needed - unspendable output
Custom Templates
Create your own script templates:
class TimeLockTemplate implements ScriptTemplate {
lock(lockTime: number, publicKeyHash: string): Script {
return new Script()
.writeNumber(lockTime)
.writeOpCode(OpCode.OP_CHECKLOCKTIMEVERIFY)
.writeOpCode(OpCode.OP_DROP)
.writeOpCode(OpCode.OP_DUP)
.writeOpCode(OpCode.OP_HASH160)
.writeBin(publicKeyHash)
.writeOpCode(OpCode.OP_EQUALVERIFY)
.writeOpCode(OpCode.OP_CHECKSIG)
}
unlock(signature: string, publicKey: string): Script {
return new Script()
.writeBin(signature)
.writeBin(publicKey)
}
}
Template Interface
All templates implement the ScriptTemplate interface:
interface ScriptTemplate {
lock(...args: any[]): Script
unlock(...args: any[]): Script
estimateLength?(args: any[]): number
}
Benefits
Reusability
- Standard patterns for common use cases
- Consistent implementation across applications
- Reduced development time
Security
- Well-tested script patterns
- Reduced risk of script errors
- Best practice implementations
Maintainability
- Clear separation of script logic
- Easy to update and modify
- Testable components
Working with Templates
Transaction Integration
// Use template in transaction
const output = {
satoshis: 1000,
lockingScript: template.lock(publicKeyHash)
}
const input = {
sourceTransaction: prevTx,
sourceOutputIndex: 0,
unlockingScript: template.unlock(privateKey, signature)
}
Fee Estimation
// Estimate script size for fee calculation
const estimatedSize = template.estimateLength([publicKeyHash])
const fee = estimatedSize * feePerByte
Advanced Patterns
Multi-Signature
class MultiSigTemplate implements ScriptTemplate {
lock(threshold: number, publicKeys: string[]): Script {
// Implementation for m-of-n multisig
}
unlock(signatures: string[]): Script {
// Implementation for signature collection
}
}
Conditional Scripts
class ConditionalTemplate implements ScriptTemplate {
lock(condition: Script, trueScript: Script, falseScript: Script): Script {
// Implementation for IF/ELSE logic
}
}
Best Practices
- Use standard templates when possible
- Test custom templates thoroughly
- Document template parameters clearly
- Consider script size and complexity
- Validate inputs before script creation
Next Steps
- Learn about Digital Signatures for script authorization
- Understand Transaction Structure integration
- Explore Key Management for script security