Exemplo n.º 1
0
def disassemble_multisig(redeem_script):
    # take apart a standard multisig's redeem/witness script, and return M/N and offset of
    # one pubkey (if provided) involved
    # - can only for multisig
    # - expect OP_1 (pk1) (pk2) (pk3) OP_3 OP_CHECKMULTISIG for 1 of 3 case
    # - returns M, N, (list of pubkeys)
    from serializations import disassemble

    M, N = -1, -1

    # generator
    dis = disassemble(redeem_script)

    # expect M value first
    M, opcode = next(dis)
    assert opcode == None and isinstance(M, int), 'garbage at start'

    pubkeys = []
    for offset, (data, opcode) in enumerate(dis):
        if opcode == OP_CHECKMULTISIG:
            # should be last byte
            break
        if isinstance(data, int):
            N = data
        else:
            pubkeys.append(data)
    else:
        raise AssertionError("end fall")

    assert len(pubkeys) == N
    assert 1 <= M <= N <= 20, 'M/N range'  # will also happen if N not encoded.

    return M, N, pubkeys
def disassemble_multisig(redeem_script):
    # Take apart a standard multisig's redeem/witness script, and return M/N and public keys
    # - only for multisig scripts, not general purpose
    # - expect OP_1 (pk1) (pk2) (pk3) OP_3 OP_CHECKMULTISIG for 1 of 3 case
    # - returns M, N, (list of pubkeys)
    # - for very unlikely/impossible asserts, dont document reason; otherwise do.
    from serializations import disassemble

    M, N = disassemble_multisig_mn(redeem_script)
    assert 1 <= M <= N <= MAX_SIGNERS, 'M/N range'
    assert len(redeem_script) == 1 + (N * 34) + 1 + 1, 'bad len'

    # generator function
    dis = disassemble(redeem_script)

    # expect M value first
    ex_M, opcode =  next(dis)
    assert ex_M == M and opcode == None, 'bad M'

    # need N pubkeys
    pubkeys = []
    for idx in range(N):
        data, opcode = next(dis)
        assert opcode == None and len(data) == 33, 'data'
        assert data[0] == 0x02 or data[0] == 0x03, 'Y val'
        pubkeys.append(data)

    assert len(pubkeys) == N

    # next is N value
    ex_N, opcode = next(dis)
    assert ex_N == N and opcode == None

    # finally, the opcode: CHECKMULTISIG
    data, opcode = next(dis)
    assert opcode == OP_CHECKMULTISIG

    # must have reached end of script at this point
    try:
        next(dis)
        raise AssertionError("too long")
    except StopIteration:
        # expected, since we're reading past end
        pass

    return M, N, pubkeys