Script templates
Script templates describe known script shapes. Each template can tell whether a script matches, extract the
values in it, build Locking and Unlocking Script builders, and say whether a set of Public Keys can spend it. The
ScriptTemplateRegistry holds the templates, and a wallet uses it to classify the Outputs it receives.
The built-in templates are P2PKH, P2PK, P2SH, P2MS, OP_RETURN, AUTHOR_IDENTITY (Author Identity
Protocol), B_PROTOCOL (B:// files) and HODLOCKER.
The examples use the keys and the fundingTransaction helper described in About the examples.
Identifying a script
Section titled “Identifying a script”TemplateRegistry.initialize(); // once, at start-up, to register the built-in templatesfinal registry = ScriptTemplateRegistry(); // a singleton
registry.identifyScriptType(p2pkh); // 'P2PKH'registry.identifyScriptType(opReturn); // 'OP_RETURN'registry.identifyScriptType(multisig); // 'P2MS'registry.identifyScriptType(custom); // null: no template matchesExtracting values
Section titled “Extracting values”extractScriptInfo returns a map whose keys depend on the template: pubKeyHash for P2PKH, publicKey for P2PK,
scriptHash for P2SH, and threshold, totalKeys and publicKeys for P2MS.
final info = registry.extractScriptInfo(p2pkh)!;info['type']; // 'P2PKH'HEX.encode(info['pubKeyHash']); // 94837d2d5d6106aa97db38957dcc294181ee91e9Can my keys spend it?
Section titled “Can my keys spend it?”final myKeys = [aliceKey.publicKey];
registry.canBeSatisfiedBy(mine, myKeys); // trueregistry.canBeSatisfiedBy(theirs, myKeys); // false// For multisig the answer means "holds at least one of the keys", not "can sign alone".registry.canBeSatisfiedBy(multisig, myKeys); // true, although this 2-of-2 also needs BobBuilding by template name
Section titled “Building by template name”createBuilder and createUnlockingBuilder take the template’s parameters as a map, which suits scripts that are
described in configuration or received over an API:
final locker = registry.createBuilder('P2PKH', { 'pubKeyHash': Uint8List.fromList(HEX.decode(myAddress.pubkeyHash160)),})!;final script = locker.getScriptPubkey(); // same bytes as P2PKHLockBuilder.fromAddress(myAddress)Your own templates
Section titled “Your own templates”We implement ScriptTemplate and register it:
/// Recognises the locking script `OP_ADD OP_5 OP_EQUAL`.class AddFivePuzzleTemplate implements ScriptTemplate { @override String get name => 'ADD_FIVE';
@override bool matches(SVScript script) => script.toHex() == SVScript.fromString('OP_ADD OP_5 OP_EQUAL').toHex();
@override Map<String, dynamic> extractScriptInfo(SVScript script) => {'type': name};
@override bool canBeSatisfiedBy(List<SVPublicKey> availableKeys, SVScript script) => matches(script); // no key needed
@override LockingScriptBuilder createBuilder(Map<String, dynamic> params) => DefaultLockBuilder.fromScript(SVScript.fromString('OP_ADD OP_5 OP_EQUAL'));
@override UnlockingScriptBuilder createUnlockingBuilder(Map<String, dynamic> params) => DefaultUnlockBuilder.fromScript(ScriptBuilder().number(params['a']).number(params['b']).build());}ScriptTemplateRegistry().register(AddFivePuzzleTemplate());ScriptTemplateRegistry().identifyScriptType(SVScript.fromString('OP_ADD OP_5 OP_EQUAL')); // 'ADD_FIVE'The registry checks templates in the order they were registered, and returns the first match.

