Custom Templates
Overview
Basic Template Creation
import {
Transaction,
PrivateKey,
PublicKey,
Script,
OP,
LockingScript,
UnlockingScript
} from '@bsv/sdk'
/**
* Basic Custom Template
*
* Simple template for a password-locked output
*/
class PasswordLockTemplate {
private password: string
constructor(password: string) {
this.password = password
}
/**
* Create locking script
*
* Requires: <password> <signature> <pubkey>
*/
lock(publicKeyHash: number[]): LockingScript {
return {
script: (): Script => {
const script = new Script()
// Password verification
const passwordHash = Buffer.from(this.hashPassword(this.password), 'hex')
script.writeOpCode(OP.OP_HASH256)
script.writeBin(passwordHash)
script.writeOpCode(OP.OP_EQUALVERIFY)
// Standard P2PKH verification
script.writeOpCode(OP.OP_DUP)
script.writeOpCode(OP.OP_HASH160)
script.writeBin(Buffer.from(publicKeyHash))
script.writeOpCode(OP.OP_EQUALVERIFY)
script.writeOpCode(OP.OP_CHECKSIG)
return script
}
}
}
/**
* Create unlocking script
*
* Provides: <password> <signature> <pubkey>
*/
unlock(privateKey: PrivateKey, password: string): UnlockingScript {
return {
sign: async (tx: Transaction, inputIndex: number) => {
const script = new Script()
// Get locking script for this input
const input = tx.inputs[inputIndex]
const lockingScript = input.sourceTransaction?.outputs[input.sourceOutputIndex]?.lockingScript
if (!lockingScript) {
throw new Error('Cannot find locking script for input')
}
// Create signature
const preimage = input.getPreimage(lockingScript)
const signature = privateKey.sign(preimage)
// Build unlocking script: <sig> <pubkey> <password>
script.writeBin(signature.toDER())
script.writeBin(privateKey.toPublicKey().encode())
script.writeBin(Buffer.from(password, 'utf8'))
return script
},
estimateLength: async () => {
return 150 // Approximate length
}
}
}
/**
* Hash password for script
*/
private hashPassword(password: string): string {
const hash = require('crypto')
.createHash('sha256')
.update(password)
.digest()
return require('crypto')
.createHash('sha256')
.update(hash)
.digest('hex')
}
}
/**
* Usage Example
*/
async function basicTemplateExample() {
const template = new PasswordLockTemplate('my-secret-password')
const privateKey = PrivateKey.fromRandom()
// Create a transaction with password-locked output
const tx = new Transaction()
tx.addInput({
sourceTXID: 'funding-tx...',
sourceOutputIndex: 0,
unlockingScriptTemplate: template.unlock(privateKey, 'my-secret-password'),
sequence: 0xffffffff
})
tx.addOutput({
satoshis: 50000,
lockingScript: template.lock(privateKey.toPublicKey().toHash()).script()
})
await tx.sign()
console.log('Password-locked transaction created')
console.log('Transaction ID:', tx.id('hex'))
}Timelock Template
Multisig Template
Conditional Template
Related Examples
See Also
Last updated
