Signature Templates

When a contract function has a sig parameter, it needs a cryptographic signature from a private key for the spending transaction. In place of a signature, a SignatureTemplate can be passed, which will generate the correct signature when the transaction is built.

Tip: SignatureTemplate can be used with a Contract as a function argument to generate a signature automatically, or can be used in the TransactionBuilder to create an Unlocker for a P2PKH UTXO.

SignatureTemplate

Constructor

from cashscript_py import SignatureTemplate

alice_signature_template = SignatureTemplate(
    "L4vmKsStbQaCvaKPnCzdRArZgdAxTqVx8vjMGLW5nHtWdRguiRi1"
)

The signer can be:

  • WIF string

  • 32-byte secret key (bytes)

  • hex string (with or without 0x prefix)

Example

from cashscript_py import Output, TransactionBuilder

transfer_details = await (
    TransactionBuilder(provider)
    .add_input(selected_contract_utxo, contract.unlock["transfer"](alice_signature_template))
    .add_output(Output(to="bitcoincash:qrhea03074073ff3zv9whh0nggxc7k03ssh8jv9mkx", amount=10_000))
    .send()
)

The hashtype and signature_algorithm options are covered under Advanced usage.

SignatureTemplate methods

unlock_p2pkh()

Importantly, SignatureTemplate can also be used to generate the Unlocker for a P2PKH UTXO:

signature_template.unlock_p2pkh() -> Unlocker

Example

alice_utxos = await provider.get_utxos(alice_address)
transaction_builder.add_input(alice_utxos[0], alice_template.unlock_p2pkh())

get_public_key()

signature_template.get_public_key() -> bytes

Get the matching compressed public key (33 bytes).

Example

alice_public_key = alice_template.get_public_key()

sign_message_hash()

signature_template.sign_message_hash(message_hash_32: bytes) -> bytes

Sign a 32-byte message hash (not a transaction preimage). This is useful for generating signatures for datasig use cases.

Example

import hashlib

message_hash_32: bytes = hashlib.sha256(bytes.fromhex("00" * 32)).digest()
signature: bytes = alice_template.sign_message_hash(message_hash_32)

Advanced usage

HashType

The default hashtype is HashType.SIGHASH_ALL | HashType.SIGHASH_UTXOS because this is typically the most secure option for smart contract use cases.

Available flags (from the CashScript-Py implementation):

class HashType(Flag):
    SIGHASH_ALL = 0x01
    SIGHASH_NONE = 0x02
    SIGHASH_SINGLE = 0x03
    SIGHASH_UTXOS = 0x20
    SIGHASH_FORKID = 0x40
    SIGHASH_ANYONECANPAY = 0x80

Example

from cashscript_py import HashType, SignatureTemplate

signature_template = SignatureTemplate(
    wif,
    hashtype=HashType.SIGHASH_ALL | HashType.SIGHASH_UTXOS,
)
configured_hash_type = signature_template.get_hash_type()

SignatureAlgorithm

The signature_algorithm parameter determines which cryptographic algorithm is used for signing. By default, the modern and compact Schnorr algorithm is used.

Available flags (from the CashScript-Py implementation):

class SignatureAlgorithm(Flag):
    ECDSA = 0x00
    SCHNORR = 0x01

Example

from cashscript_py import HashType, SignatureAlgorithm, SignatureTemplate

signature_template = SignatureTemplate(
    wif,
    signature_algorithm=SignatureAlgorithm.SCHNORR,
)
configured_signature_algorithm = signature_template.get_signature_algorithm()

Notes on contract sig arguments

CashScript-Py accepts a SignatureTemplate as a function argument for sig parameters. The Contract will:

  1. build the signature hash for the input being signed, and

  2. ask the template to generate the correct signature at build time.

This allows you to pass SignatureTemplate(...) in place of a raw signature.