opcodeCheckMultiSig treats the top item on the stack as an integer number of public keys, followed by that many entries as raw data representing the public keys, followed by the integer number of signatures, followed by that many entries as raw data representing the signatures. Due to a bug in the
(op *opcode, data []byte, vm *Engine)
| 2223 | // Stack transformation: |
| 2224 | // [... dummy [sig ...] numsigs [pubkey ...] numpubkeys] -> [... bool] |
| 2225 | func opcodeCheckMultiSig(op *opcode, data []byte, vm *Engine) error { |
| 2226 | // If we're doing tapscript execution, then this op code is disabled. |
| 2227 | if vm.taprootCtx != nil { |
| 2228 | str := fmt.Sprintf("OP_CHECKMULTISIG and " + |
| 2229 | "OP_CHECKMULTISIGVERIFY are disabled during " + |
| 2230 | "tapscript execution") |
| 2231 | return scriptError(ErrTapscriptCheckMultisig, str) |
| 2232 | } |
| 2233 | |
| 2234 | numKeys, err := vm.dstack.PopInt() |
| 2235 | if err != nil { |
| 2236 | return err |
| 2237 | } |
| 2238 | |
| 2239 | numPubKeys := int(numKeys.Int32()) |
| 2240 | if numPubKeys < 0 { |
| 2241 | str := fmt.Sprintf("number of pubkeys %d is negative", |
| 2242 | numPubKeys) |
| 2243 | return scriptError(ErrInvalidPubKeyCount, str) |
| 2244 | } |
| 2245 | if numPubKeys > MaxPubKeysPerMultiSig { |
| 2246 | str := fmt.Sprintf("too many pubkeys: %d > %d", |
| 2247 | numPubKeys, MaxPubKeysPerMultiSig) |
| 2248 | return scriptError(ErrInvalidPubKeyCount, str) |
| 2249 | } |
| 2250 | vm.numOps += numPubKeys |
| 2251 | if vm.numOps > MaxOpsPerScript { |
| 2252 | str := fmt.Sprintf("exceeded max operation limit of %d", |
| 2253 | MaxOpsPerScript) |
| 2254 | return scriptError(ErrTooManyOperations, str) |
| 2255 | } |
| 2256 | |
| 2257 | pubKeys := make([][]byte, 0, numPubKeys) |
| 2258 | for i := 0; i < numPubKeys; i++ { |
| 2259 | pubKey, err := vm.dstack.PopByteArray() |
| 2260 | if err != nil { |
| 2261 | return err |
| 2262 | } |
| 2263 | pubKeys = append(pubKeys, pubKey) |
| 2264 | } |
| 2265 | |
| 2266 | numSigs, err := vm.dstack.PopInt() |
| 2267 | if err != nil { |
| 2268 | return err |
| 2269 | } |
| 2270 | numSignatures := int(numSigs.Int32()) |
| 2271 | if numSignatures < 0 { |
| 2272 | str := fmt.Sprintf("number of signatures %d is negative", |
| 2273 | numSignatures) |
| 2274 | return scriptError(ErrInvalidSignatureCount, str) |
| 2275 | |
| 2276 | } |
| 2277 | if numSignatures > numPubKeys { |
| 2278 | str := fmt.Sprintf("more signatures than pubkeys: %d > %d", |
| 2279 | numSignatures, numPubKeys) |
| 2280 | return scriptError(ErrInvalidSignatureCount, str) |
| 2281 | } |
| 2282 |
no test coverage detected
searching dependent graphs…