diff --git a/txscript/standard.go b/txscript/standard.go index 7a61e365f6..470225e090 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -648,27 +648,21 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // CalcMultiSigStats returns the number of public keys and signatures from // a multi-signature transaction script. The passed script MUST already be // known to be a multi-signature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func CalcMultiSigStats(script []byte) (int, int, error) { - pops, err := parseScript(script) - if err != nil { - return 0, 0, err - } - - // A multi-signature script is of the pattern: - // NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG - // Therefore the number of signatures is the oldest item on the stack - // and the number of pubkeys is the 2nd to last. Also, the absolute - // minimum for a multi-signature script is 1 pubkey, so at least 4 - // items must be on the stack per: - // OP_1 PUBKEY OP_1 OP_CHECKMULTISIG - if len(pops) < 4 { + // The public keys are not needed here, so pass false to avoid the extra + // allocation. + const scriptVersion = 0 + details := extractMultisigScriptDetails(scriptVersion, script, false) + if !details.valid { str := fmt.Sprintf("script %x is not a multisig script", script) return 0, 0, scriptError(ErrNotMultisigScript, str) } - numSigs := asSmallInt(pops[0].opcode.value) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) - return numPubKeys, numSigs, nil + return details.numPubKeys, details.requiredSigs, nil } // payToPubKeyHashScript creates a new script to pay a transaction diff --git a/txscript/standard_test.go b/txscript/standard_test.go index 37dd8f8a37..582d30eee4 100644 --- a/txscript/standard_test.go +++ b/txscript/standard_test.go @@ -832,7 +832,7 @@ func TestCalcMultiSigStats(t *testing.T) { name: "short script", script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" + "e03909a67962e0ea1f61d", - err: scriptError(ErrMalformedPush, ""), + err: scriptError(ErrNotMultisigScript, ""), }, { name: "stack underflow", @@ -843,11 +843,7 @@ func TestCalcMultiSigStats(t *testing.T) { }, { name: "multisig script", - script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" + - "2ffef55846514dacbdcbbdd652c849d395b4384022100" + - "e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" + - "07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " + - "0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" + + script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" + "0357b3a7886211ab414d55a 1 CHECKMULTISIG", err: nil, },