Skip to content

Signing

The TransactionSigner signs one Input at a time. It computes the Sighash digest for the Input, signs it with its key, and hands the resulting TransactionSignature to the Input’s unlocking script builder, which turns it into the Unlocking Script.

The builder calls it for every Input that has a signer. We call it ourselves when we sign later, for multisig, or after setting the lock time. The examples use the setup from the Transaction builder, and an unsigned Transaction tx that spends utxo.

TransactionSigner signer = new TransactionSigner(SIGHASH, alice);
signer.sign(tx, utxo, 0); // adds the Signature to Input 0's unlocker
// What the signer just did, should we need it.
TransactionSignature signature = signer.getSignature();
byte[] sighashDigest = signer.getHash();

In the preceding example the sign() method takes three parameters:

  • the Transaction being signed,
  • the Output being spent, whose Locking Script and amount are part of the digest,
  • the index of the Input we are signing.

We pass the Output from the funding Transaction, or build one with new TransactionOutput(amount, script) when we only have those two values.

Do note that a wrong amount or script gives a Signature that fails verification, with no error at signing time.

The getters describe the last sign() call: getSignature(), getHash() (the 32-byte digest that was signed), getSigHashType() and getSignedTransaction(). getPreImage() is not filled in by sign(), so we use SigHash (below) for the preimage.

sign() has an overload that takes the key and the Sighash type for this one call.

// One signer, with the key and Sighash type given for this call only.
TransactionSigner signer = new TransactionSigner(SIGHASH, alice);
signer.sign(tx, utxo, 0, alice, SigHashType.ALL.value | SigHashType.FORKID.value);

The digest is the double SHA-256 of a preimage, i.e. the serialised parts of the Transaction that the Sighash type covers. Scripts that inspect the spending Transaction (the OP_PUSH_TX technique) receive the preimage in their Unlocking Script. SigHash produces it for us.

// The Sighash preimage is the bytes whose double SHA-256 the Signature commits to.
// Scripts that inspect their own transaction (OP_PUSH_TX) take this as input.
byte[] preimage = new SigHash().getSighashPreimage(tx, SIGHASH, 0, utxo.getScript(), utxo.getAmount());
// signPreimage() hashes and signs it.
TransactionSignature fromPreimage = new TransactionSigner(SIGHASH, alice).signPreimage(alice, preimage, SIGHASH);

SigHash.createHash() returns the digest directly, the same bytes that TransactionSigner.getHash() reports. Signatures are deterministic (RFC 6979), so signPreimage() and sign() produce identical Signatures for the same Input.

Please note that getSighashPreimage() cuts the script code at the first OP_CODESEPARATOR, which is what an OP_PUSH_TX script sitting after a code separator expects. createHash() and TransactionSigner use the full script, which is right for an ordinary OP_CHECKSIG.