2016-11-02 02:30:37 +01:00
|
|
|
// m [pubKeys ...] n OP_CHECKMULTISIG
|
|
|
|
|
2019-03-07 06:16:45 +01:00
|
|
|
import { Stack } from '../../payments';
|
2019-03-06 13:38:36 +01:00
|
|
|
import * as bscript from '../../script';
|
|
|
|
import { OPS } from '../../script';
|
2019-03-07 06:16:45 +01:00
|
|
|
import * as types from '../../types';
|
2019-03-06 13:38:36 +01:00
|
|
|
const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1
|
2016-11-02 02:30:37 +01:00
|
|
|
|
2019-03-06 13:38:36 +01:00
|
|
|
export function check(
|
2019-03-07 06:16:45 +01:00
|
|
|
script: Buffer | Stack,
|
2019-03-06 13:38:36 +01:00
|
|
|
allowIncomplete?: boolean,
|
|
|
|
): boolean {
|
2019-03-07 06:16:45 +01:00
|
|
|
const chunks = bscript.decompile(script) as Stack;
|
2016-11-02 02:30:37 +01:00
|
|
|
|
2019-03-06 13:38:36 +01:00
|
|
|
if (chunks.length < 4) return false;
|
|
|
|
if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) return false;
|
|
|
|
if (!types.Number(chunks[0])) return false;
|
|
|
|
if (!types.Number(chunks[chunks.length - 2])) return false;
|
2019-03-07 06:16:45 +01:00
|
|
|
const m = (chunks[0] as number) - OP_INT_BASE;
|
|
|
|
const n = (chunks[chunks.length - 2] as number) - OP_INT_BASE;
|
2016-11-02 02:30:37 +01:00
|
|
|
|
2019-03-06 13:38:36 +01:00
|
|
|
if (m <= 0) return false;
|
|
|
|
if (n > 16) return false;
|
|
|
|
if (m > n) return false;
|
|
|
|
if (n !== chunks.length - 3) return false;
|
|
|
|
if (allowIncomplete) return true;
|
2016-11-02 02:30:37 +01:00
|
|
|
|
2019-03-07 06:16:45 +01:00
|
|
|
const keys = chunks.slice(1, -2) as Buffer[];
|
2019-03-06 13:38:36 +01:00
|
|
|
return keys.every(bscript.isCanonicalPubKey);
|
2016-11-02 02:30:37 +01:00
|
|
|
}
|
2019-03-21 16:15:37 +01:00
|
|
|
check.toJSON = (): string => {
|
2019-03-06 13:38:36 +01:00
|
|
|
return 'multi-sig output';
|
|
|
|
};
|