verify method
Implementation
@override
bool verify() {
final psbtInputs = txData.psbt.inputs;
if (psbtInputs.isEmpty) return false;
final List<_Prevout> prevouts;
try {
prevouts = _gatherPrevouts();
} catch (_) {
return false;
}
final prevOutScripts = prevouts.map((p) => p.scriptHex).toList();
final prevOutValues = prevouts.map((p) => p.value).toList();
for (int i = 0; i < psbtInputs.length; i++) {
final input = psbtInputs[i];
if (txData.isTaproot) {
final sig = input.taprootKeySpendSignature;
final outputKey = prevouts[i].taprootOutputKey;
if (sig == null || outputKey == null) return false;
final Uint8List signatureBytes;
try {
signatureBytes = fromHex(sig);
} catch (_) {
return false;
}
if (signatureBytes.length != 64 && signatureBytes.length != 65) {
return false;
}
final signatureHashType =
signatureBytes.length == 65 ? signatureBytes.last : 0x00;
if (!_validTaprootSighashTypes.contains(signatureHashType) ||
(signatureBytes.length == 65 && signatureHashType == 0x00) ||
(input.sighashType != null &&
input.sighashType != signatureHashType)) {
return false;
}
final String sigHashHex;
try {
sigHashHex = txData.psbt.unsignedTransaction!.getTaprootSigHash(
i,
prevOutScripts,
prevOutValues,
hashType: signatureHashType,
);
} catch (_) {
return false;
}
final rawSignature =
dynamicToString(signatureBytes.sublist(0, 64));
try {
if (!Schnorr.verify(outputKey, rawSignature, sigHashHex)) return false;
} catch (_) {
return false;
}
} else {
final partialSigs = input.partialSigs;
if (partialSigs == null || partialSigs.length != 2) return false;
final signature = partialSigs[0];
final Uint8List signatureBytes;
final Uint8List publicKey;
try {
signatureBytes = fromHex(signature);
publicKey = fromHex(partialSigs[1]);
} catch (_) {
return false;
}
if (signatureBytes.isEmpty || signatureBytes.last != 0x01) {
return false;
}
final expectedPublicKeyHash = prevouts[i].p2pkhPublicKeyHash;
if (expectedPublicKeyHash == null ||
dynamicToString(sha160fromByte(publicKey)) !=
dynamicToString(expectedPublicKeyHash)) {
return false;
}
final sigHashHex = txData.psbt.unsignedTransaction!.getSigHash(
i,
prevouts[i].fullOutputHex,
false,
);
if (!EcdaSignature.verifyDerWithHashType(
sigHashHex, publicKey, signature)) {
return false;
}
}
}
return true;
}