Vision to Reality 2: Managing State and Ownership 
In the previous article we demonstrated how the Engine could use an invitation system to coordinate and execute on a request for 100.00 MUSD fungible tokens.
In this article, we are going to go over how a templating engine could manage contract state, private keys, how it would estimate ownership in shared outputs as well as demonstrate how to sign and verify messages using a P2PKH template.
State and Ownership 
Managing state 
After a transaction has been broadcast on chain that has an output matching the locking script used in our previous request, the engine will automatically detect this output and internally connect it with the template and action as well as keep track of the original variables.
However, if you remember from the previous article the ownerKey was generated on-demand as-needed, but in order to spend this new output we would need the same private key as was used to create the lockscript. So let's revisit the receivingLockingScript, this time without shortening it:
receivingLockingScript:
{
	name: 'Received',
	description: 'Funds received without wallet coordination.',
	icon: 'address',
	// Defines how spending future received funds should be authorized.
	lockingType: 'standard',
	lockingScript: 'lockP2PKH',
	// Define a default unlocking script to be used when no action provided script is present.
	unlockingScript: 'unlockP2PKH',
	roles:
	{
		owner:
		{
			// The only state that is required to be persisted when receiving funds is the owners private key.
			state: [],
			secrets: [ 'ownerKey' ],
			// List actions that can be taken with the ownerKey for each address/lockscript.
			actions: [ 'sign', 'verify', 'sendSatoshis', 'sendFungibleTokens', 'sendNonfungibleTokens', 'burnFungibleTokens', 'burnNonfungibleTokens' ],
			// Indicates how much of received funds should be part of a wallets total balance.
			balance:
			{
				satoshis: true,
				fungibleTokens: true,
				nonFungibleToken: true,
			},
			// Indicate when received funds should be considered in automatic coin selection to meet input requirements of other transactions.
			selectable: true,
			// Indicate that received funds are not considered good privacy.
			privacy: false,
		},
	},
}Note that the description here does not match the action we had earlier. This is intentional, as when any lockscript is generated, it is the engine's responsibility to start tracking all activity related to it. When such activity can be linked to an action, it will use the descriptions provided by that action. Sometimes, though, there is activity that the engine cannot predict, such as when you receive an airdrop or someone dusts your address.
The name and description of the lockscript are then used for such outputs that cannot be linked to known past actions, allowing us to provide human meaningful context even for uncoordinated activity.
You can also see that there is a default unlocking script, which is used when the engine needs to use an output on this lockscript and has not received any explicit instructions on how to unlock it.
The important part for us right now though, is the state/secrets.
// The only state that is required to be persisted when receiving funds is the owners private key.
state: []
secrets: [ 'ownerKey' ]When the engine is asked to create either an output or a lockingscript, the template can define a set of variables that are to be automatically managed. The engine would then take this state and internally tie it to the output, or any output using the specific lockscript.
When the output is later spent, the state attached to it will be made available to satisfy any constraints originating from the same template. In this P2PKH example, the ownerKey is marked as part of the secrets which is a subset of the full state that will not be shared when doing invitations or similar actions.
In more advanced uses, the state might be defined at one transaction, but only be needed several transactions later. In these cases, it is up to the template authors to define outputs to carry the state from one transaction to the next until it is no longer needed.
Note that a result of this behaviour is that state has a lifecycle and once an output is spent, any state attached to that output can be archived into history or even pruned entirely, depending on the needs of the wallet or application.
Managing state is likely the most complex and most valuable part of the templating system, and much more can be said on this matter. We will go into more detail in follow-up articles.
What is ownership? 
There are a few more parts of the receivingLockingScript left to go over that relates to ownership and control of outputs: actions, balance, selectable and privacy.
These properties provide information to an app or wallet that uses the engine. Let's go over each of them to get a better understanding of what they do:
// List actions that can be taken with the ownerKey for each address/lockscript.
actions: [ 'sign', 'verify', 'sendSatoshis', 'sendFungibleTokens', 'sendNonfungibleTokens', 'burnFungibleTokens', 'burnNonfungibleTokens' ]The actions list provides references to actions that you might be able to take with a given output or the state attached to an output.
In the P2PKH template, these can be summarized as actions to sign and verify messages as well as sending and burning value.
This allows an app or wallet to present possible actions when the user is looking at a given output or address. Some of the actions listed here may have additional constraints, for example:
// Sending is only available for outputs that have fungible tokens on them.
condition: '$(OP_INPUTINDEX OP_UTXOTOKENAMOUNT <0> OP_GREATERTHAN)'The sendFungibleTokens action has a condition that allows it to be ignored if the input does not have any fungible tokens on it.
Apart from potential actions, there is also a balance property which can be used to get a better understanding of how much of an output is estimated to owned by the user:
balance:
{
	satoshis: true,
	fungibleTokens: true,
	nonFungibleToken: true,
}In the P2PKH example, these are set to true to indicate that the full output is estimated to be owned by the owner. However, these fields can also be set to false, or a number.
In more advanced cases, these fields would be CashASM evaluations that would be able to determine values based on the variables in the state, and in some cases they would be impossible to define and would be undefined.
It is up to the app or wallet to determine how they want to use, or not use, this information.
Finally, there are two properties relating to coin selection: selectable and privacy:
// Indicate when received funds should be considered in automatic coin selection.
selectable: true
// Indicate that received funds are not considered good privacy.
privacy: falseCoin selection is a vast field with no best answer, so these are provided as additional information that a coin selection algorithm may use, and not as strict directives for when and how to do coin selection.
The selectable property allows the template authors to indicate if it is sensible to use an output in automatic coin selection and can be either true (may be used), false (should not be used) or can be left undefined.
The privacy property allows the template authors to indicate what level of privacy an output has, which can be helpful to avoid mixing of inputs of different levels of privacy.
Other actions 
Before we wrap up, let's take a deeper look at the sign and verifyactions:
sign:
{
	name: 'Sign Message',
	description: 'Signs a provided message using the Bitcoin message signing protocol.',
	icon: 'sign',
	variables: [ 'message' ],
	data: [ 'messageSignature' ],
}
verify:
{
	name: 'Verify Message Signature',
	description: 'Verifies a provided message signature according to the Bitcoin message signing protocol.',
	icon: 'verify',
	variables: [ 'messageSignature', 'message' ],
	data: [ 'messageSignatureValidity' ],
}Contrary to previous actions we have looked at, these do not result in transactions, but instead provide arbitrary data.
Signing message 
In the messageSignature definition, we can see references to a messagePrefix constant:
messageSignature:
{
	// Evaluate CashASM expression to get the signature needed.
	value: '$(<messagePrefix> <message> OP_CAT <ownerKey.data_signature.top_stack_element>)',
	type: 'bytes',
	hint: 'signature',
}messagePrefix:
{
	name: 'Message Prefix',
	description: 'Standard message prefix used in the bitcoin signed message protocol.',
	type: 'bytes',
	// Value is enforce to the bitcoin signing magic string:
	// "\x18Bitcoin Signed Message:\n"
	value: '0x18426974636f696e205369676e6564204d6573736167653a0a',
}Together, these encode the standard bitcoin message signing procedure to safely sign an arbitrary message using the ownerKey from any given address or output. This is done without exposing the keys to 3rd parties or allowing arbitrary signing of potentially dangerous messages.
Note that a malicious template can already create dangerous situations by providing false descriptions of the actions being taken or request signing of such dangerous messages, and that it is important to properly audit any templates before trusting them.
Validating signatures 
The validation of a signature is done in a similar way:
messageSignatureValidity:
{
	// Evalute the validity of the message with the owners public key.
	value: '$(<messageSignature> <messagePrefix> <message> OP_CAT <ownerKey.publicKey> OP_CHECKDATASIG)';
	type: 'integer',
	hint: 'script_boolean',
}This means that any wallet that uses this P2PKH template would have this feature without needing to add any special handling or code for it. Simply find any address/lockscript or output, look at the associated actions and initiate an action to sign or verify a message.
The value of templates 
Together with the previous article on how to make and handle a payment request, we have now covered the full featureset of a P2PKH template. We have gone into detail on how the engine can go from having almost no understanding of the standardness approved P2PKH lockscript, to being able to create all necessary parts required to complete a token request, manage the full lifecycle of related state and use associated functionality such as signing and verifying arbitrary messages.
By encoding the definition of state, secrets and private keys and how they are used in templates in a generalized way, we can apply the same patterns and processes to any template regardless of complexity, as long as it stays within the confines of the Bitcoin Cash rule set.
This means that we can now build new applications both faster and safer, while providing a significantly better user experience.
Increased safety 
In the traditional wallet and app ecosystem today, the default is to run on HD wallets using seed words for backup and recovery.
With every new feature added to the Bitcoin Cash blockchain that empowers smart contract developers, the number of use cases where the wallet seed is insufficient to restore full access after recovering from backup grows.
Contracts by nature are stateful and loss of state is often equivalent to loss of funds. While this can be mitigated to some degree by carrying state in token commitments, it has the tradeoff of exposing that state to the world. Further, some state, such as your prediction in a BCH Guru bet, must be kept secret, and cannot be safely stored in a token commitment.
By addressing the need for state management in modern smart contracts, we reduce the risk of state loss and therefore improve safety for users.
Further, by creating an engine that is capable of both generating and storing keys, keeping them isolated, and restricting their use to template defined actions, we provide additional safety in terms of key management.
This is also a missing piece in order to achieve fully non-custodial applications, where both control of all keys, as well as all decision making around those keys resides entirely with the user's wallet.
Finally, by creating an invitation and coordination mechanic that doesn't rely on single-key operation and that does template based validation of provided data, we improve safety for users when interacting with 3rd party distributed applications.
Improved user experience 
With templates, every transaction, input, output, lockscript and address can be described with dynamically evaluated CashASM names and descriptions. Further, every variable or input required by the user can be described as well, and their type and data can be validated.
As a result, the need for technical identifiers is massively reduced.
Further, by having contextual actions, external links and other metadata it becomes much easier for users to be empowered and stay in control.
Finally, with templates it becomes possible to estimate a users aggregate net worth across a wide variety of contracts, as well as show how much of that value is readily accessible for spending and how much is currently locked.
Higher productivity 
When using trusted templates, the correct use of a contract is directly encoded. Importing a template that someone else has made can be done to provide new features at almost no cost.
Compared to some alternatives, templates also provide a consistent way to adopt new features where previously app and wallet makers would need to import specific libraries for each feature they want, or do full bespoke implementations.
For reference, the AnyHedge library, excluding tests and examples, is 262.8 KiB large.
While it can do much more than a corresponding template, a lot of it is re-inventing the BitcoinCash domain knowledge, working with inputs and outputs etc., and my estimate is that less than a third of it would been needed if we had full template support.