2016-11-02 02:30:37 +01:00
|
|
|
// m [pubKeys ...] n OP_CHECKMULTISIG
|
|
|
|
|
|
|
|
var bscript = require('../../script')
|
|
|
|
var types = require('../../types')
|
|
|
|
var typeforce = require('typeforce')
|
2016-12-17 15:24:00 +01:00
|
|
|
var OPS = require('bitcoin-ops')
|
2016-11-02 02:30:37 +01:00
|
|
|
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
|
|
|
|
|
|
|
|
function check (script, allowIncomplete) {
|
|
|
|
var chunks = bscript.decompile(script)
|
|
|
|
|
|
|
|
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
|
|
|
|
var m = chunks[0] - OP_INT_BASE
|
|
|
|
var n = chunks[chunks.length - 2] - OP_INT_BASE
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
var keys = chunks.slice(1, -2)
|
|
|
|
return keys.every(bscript.isCanonicalPubKey)
|
|
|
|
}
|
2016-11-02 04:33:46 +01:00
|
|
|
check.toJSON = function () { return 'multi-sig output' }
|
2016-11-02 02:30:37 +01:00
|
|
|
|
|
|
|
function encode (m, pubKeys) {
|
|
|
|
typeforce({
|
|
|
|
m: types.Number,
|
|
|
|
pubKeys: [bscript.isCanonicalPubKey]
|
|
|
|
}, {
|
|
|
|
m: m,
|
|
|
|
pubKeys: pubKeys
|
|
|
|
})
|
|
|
|
|
|
|
|
var n = pubKeys.length
|
|
|
|
if (n < m) throw new TypeError('Not enough pubKeys provided')
|
|
|
|
|
|
|
|
return bscript.compile([].concat(
|
|
|
|
OP_INT_BASE + m,
|
|
|
|
pubKeys,
|
|
|
|
OP_INT_BASE + n,
|
|
|
|
OPS.OP_CHECKMULTISIG
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
function decode (buffer, allowIncomplete) {
|
|
|
|
var chunks = bscript.decompile(buffer)
|
|
|
|
typeforce(check, chunks, allowIncomplete)
|
|
|
|
|
|
|
|
return {
|
|
|
|
m: chunks[0] - OP_INT_BASE,
|
|
|
|
pubKeys: chunks.slice(1, -2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
check: check,
|
|
|
|
decode: decode,
|
|
|
|
encode: encode
|
|
|
|
}
|