Skip to main content
The verify_before_signing function checks that a PCZT matches your original request. This is a security check to detect malleation if the PCZT was handled by a third party.
Per ZIP 374: “If the entity that invoked propose_transaction is the same as the entity that is adding the signatures, and no third party may have malleated the PCZT before signing, this step may be skipped.”

When to Verify

ScenarioShould Verify?
You created and will sign the PCZTOptional
PCZT came from another systemRequired
Hardware wallet workflowRequired
Multi-party transactionRequired

Function Signature

  • TypeScript
  • Go
  • Kotlin
function verify_before_signing(
  pczt: WasmPczt,
  payments: WasmPayment[],
  expected_change: WasmExpectedTxOut[]
): void  // Throws on failure

Parameters

pczt
Pczt
required
The PCZT to verify
payments
Payment[]
required
The original payments you requested (same as passed to propose_transaction)
expected_change
ExpectedTxOut[]
required
Expected change outputs. Use inspect_pczt to get the actual change amount:
interface ExpectedTxOut {
  address: string;   // Change address
  amount: bigint;    // Change amount in zatoshis
}

Example

  • TypeScript
  • Go
import * as t2z from '@d4mr/t2z-wasm';

// Original payments (same as used in propose_transaction)
const payments = [
  new t2z.WasmPayment('u1recipient...', 500_000n, null, null)
];

// Get the actual change from the PCZT
const info = t2z.inspect_pczt(pczt.to_hex());

// Calculate change: total_orchard_output - payment_amount
const paymentTotal = payments.reduce((sum, p) => sum + p.amount, 0n);
const changeAmount = BigInt(info.total_orchard_output) - paymentTotal;

// Build expected change
const expectedChange = changeAmount > 0n 
  ? [new t2z.WasmExpectedTxOut(changeAddress, changeAmount)]
  : [];

// Verify
try {
  t2z.verify_before_signing(pczt, payments, expectedChange);
  console.log('✓ Verification passed');
} catch (err) {
  console.error('✗ Verification failed:', err.message);
  // DO NOT SIGN - PCZT may have been tampered with!
}

What Gets Verified

1

Payment Matching

Every payment in your original request must be present in the PCZT with the exact amount and address.
2

Change Verification

If you expect change, it must go to the expected address with the expected amount.
3

No Extra Outputs

The PCZT must not contain any unexpected outputs (malleation check).

Verification Errors

One of your original payments is missing from the PCZT. The PCZT may have been modified.
The PCZT contains an output that wasn’t in your original request. Possible malleation.
The change output doesn’t match expectations (wrong address or amount).

Security Considerations

Never sign a PCZT that fails verification. A malicious party could have:
  • Changed the recipient address
  • Modified the amounts
  • Added extra outputs to steal funds
If verification fails:
  1. Do not sign the PCZT
  2. Discard it and create a new one
  3. Investigate how the PCZT was modified

Skipping Verification

You can skip verification when:
  • You created the PCZT yourself
  • The PCZT never left your control
  • You’re in a development/testing environment
// Skip verification (only when safe to do so)
console.log('Skipping verification (same entity created and will sign)');

Next Step

After verification passes (or is skipped), proceed to signing the transparent inputs.